私はthis questionを見ていましたが、文字列以外の値へのバインドLabel.Content
は暗黙的なTextBlock
スタイルを適用しますが、文字列へのバインディングはそうではありません。Label.Contentを文字列ではなく文字列にバインドするときに暗黙的なTextBlockスタイルが適用されるのはなぜですか?
ここで問題を再現するいくつかのサンプルコードです:
バインド値のコードがSomeDecimal = 50;
SomeString = SomeDecimal.ToString();
され、最終結果は、暗黙的からMargin
プロパティで、次のようになります
<Window.Resources>
<Style TargetType="Label">
<Setter Property="FontSize" Value="26"/>
<Setter Property="Margin" Value="10"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontSize" Value="26"/>
<Setter Property="Margin" Value="10"/>
</Style>
</Window.Resources>
<Grid>
<StackPanel Orientation="Horizontal">
<Label Content="{Binding SomeString}" Background="Red"/>
<Label Content="{Binding SomeDecimal}" Background="Green"/>
</StackPanel>
</Grid>
TextBlockスタイルはLabelに適用され、非文字列のみにバインドされます:
のどちらのラベルは私がSnoopでVisualTreeをチェックアウトすると、私は第二のTextBlockは、暗黙的なスタイルからマージンを適用する以外、それは一方で、両方の要素のためにまったく同じに見えることがわかります
<Label>
<Border>
<ContentPresenter>
<TextBlock />
</ContentPresenter>
</Border>
</Label>
としてレンダリングされます最初はありません。
私は、デフォルトのラベルテンプレートのコピーを引き出すためにブレンドを使用しましたが、そこに奇妙な何も表示されない、と私は両方の私のラベルにテンプレートを適用すると、同じことが起こります。
<Label.Template>
<ControlTemplate TargetType="{x:Type Label}">
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
Padding="{TemplateBinding Padding}"
SnapsToDevicePixels="True">
<ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
ContentStringFormat="{TemplateBinding ContentStringFormat}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Label.Template>
またTextBlock
にデフォルトContentTemplate
を設定すると、両方の項目は、暗黙的なスタイルずにレンダリングさせるんので、WPFは、パートなどの非文字列値をレンダリングしようとすると、それはとは何かを持っている必要がありますことに留意すべきですUIの
<Window.Resources>
<Style TargetType="Label">
<Setter Property="FontSize" Value="26"/>
<Setter Property="Margin" Value="10"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
<Style x:Key="TemplatedStyle" TargetType="Label" BasedOn="{StaticResource {x:Type Label}}">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="{Binding }"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontSize" Value="26"/>
<Setter Property="Margin" Value="10"/>
</Style>
</Window.Resources>
<Grid>
<StackPanel Orientation="Horizontal">
<Label Content="{Binding SomeString}" Background="Red"/>
<Label Content="{Binding SomeDecimal}" Background="Green"/>
<Label Content="{Binding SomeString}" Background="Red"
Style="{StaticResource TemplatedStyle}"/>
<Label Content="{Binding SomeDecimal}" Background="Green"
Style="{StaticResource TemplatedStyle}"/>
</StackPanel>
</Grid>
暗黙のTextBlockのスタイルを使用して描画するUIに挿入された文字列以外の原因が、UIに挿入された文字列ではないでしょうか?ロジックは何ですかそして、これはどこで起こりますか?
この質問は私に興味をそそっていたので、古いリフレクターを始める必要がありました。まあ、これまで私が見つけたことは一つしかない。 TextBlockは単純なテキストと "複雑な"オブジェクトを区別しているようですが、両方のために2つの異なるサブクラスを使用します。残念ながら、これが終わるところです。私は特殊なスタイルや何かの痕跡を見つけることができません。 TextBlockをContentTemplateに提供し、それが何かを変更するかどうかを確認することを試してください。その場合、それはその神秘的なデフォルトテンプレートと何か関係があります。 – dowhilefor
@dowhilefor私はBlendからデフォルトのテンプレートを引っ張って両方のラベルに適用しようとしました。同じことが起こりました(その情報で更新された質問)。 WPFは 'System.String'を暗黙的なスタイリングなしで' TextBlock'としてレンダリングすることを知っていますが、文字列以外の値をレンダリングするときは、 'TextBlock'を' .ToString 'にバインドして描画します() 'を呼び出し、暗黙のスタイリングを適用します。 – Rachel
@dowhileforデフォルトの 'ContentTemplate'を' 'に設定すると暗黙のスタイルなしで両方のアイテムがレンダリングされますので、非文字列オブジェクトのデフォルトの 'ContentTemplate' –
Rachel