Tôi đang xem this question và phát hiện ra rằng ràng buộc Label.Content
với giá trị không phải chuỗi sẽ áp dụng kiểu dáng TextBlock
tiềm ẩn, tuy nhiên ràng buộc với một chuỗi thì không.Tại sao một kiểu TextBlock tiềm ẩn được áp dụng khi gắn Label.Content với một chuỗi không phải chuỗi, nhưng không phải là một chuỗi?
Dưới đây là một số mẫu mã để tạo lại vấn đề:
<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>
Trường hợp mã cho các giá trị ràng buộc là
SomeDecimal = 50;
SomeString = SomeDecimal.ToString();
Và kết quả cuối cùng trông như thế này, với Margin
tài sản từ các ngầm Kiểu nhận dạng TextBlock được áp dụng cho Nhãn được gắn với một chuỗi không phải chỉ:
Cả hai nhãn nhận được kết xuất như
<Label>
<Border>
<ContentPresenter>
<TextBlock />
</ContentPresenter>
</Border>
</Label>
Khi tôi kiểm tra VisualTree với Snoop, tôi có thể thấy rằng nó trông giống hệt nhau cho cả hai yếu tố, ngoại trừ TextBlock thứ 2 áp dụng Margin từ phong cách tiềm ẩn, trong khi đầu tiên thì không.
Tôi đã sử dụng Blend để kéo ra một bản sao của Label Template mặc định, nhưng không thấy bất cứ điều gì lạ ở đó, và khi tôi áp dụng mẫu cho cả hai nhãn của tôi, điều tương tự sẽ xảy ra.
<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>
Nó cũng cần lưu ý rằng thiết lập mặc định ContentTemplate
đến một TextBlock
không làm cho cả hai mục làm mà không có phong cách tiềm ẩn, vì vậy nó phải có cái gì để làm với khi WPF cố gắng để làm cho một giá trị không theo chuỗi như là một phần của giao diện người dùng.
<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>
gì là logic gây ra một tổ chức phi chuỗi đưa vào giao diện người dùng được rút ra sử dụng một phong cách TextBlock tiềm ẩn, nhưng một chuỗi đưa vào giao diện người dùng không? Và điều này xảy ra ở đâu?
Câu hỏi này hấp dẫn tôi, vì vậy tôi phải bắt đầu phản xạ cũ. Vâng, chỉ có một điều tôi có thể tìm thấy cho đến nay. Có vẻ như TextBlock tạo sự khác biệt giữa văn bản đơn giản và các đối tượng "phức tạp", nó sử dụng hai lớp con khác nhau cho cả hai. Thật không may đây là nơi nó kết thúc. Tôi không thể tìm thấy bất kỳ dấu vết của một phong cách chuyên ngành hoặc bất cứ điều gì. Một điều cần thử là cung cấp một ContentTemplate với một TextBlock và kiểm tra xem điều đó có thay đổi gì đó không. Trong trường hợp đó, nó có thể có một cái gì đó để làm với mẫu mặc định huyền bí đó. – dowhilefor
@dowhilefor Tôi đã thử kéo mẫu mặc định từ Blend và áp dụng nó cho cả hai nhãn, và điều tương tự xảy ra (câu hỏi được cập nhật với thông tin đó). Đoán duy nhất của tôi sẽ là WPF biết để render 'System.String' như là một' TextBlock' mà không có kiểu dáng ngầm, nhưng khi nó đi để render một giá trị không phải chuỗi, nó vẽ nó như một ràng buộc 'TextBlock' thành' .ToString() 'của đối tượng và áp dụng bất kỳ kiểu dáng tiềm ẩn nào. – Rachel
@dowhilefor Bạn là chính xác mặc dù thiết lập mặc định 'ContentTemplate' thành một' 'làm cho cả hai mục hiển thị mà không có kiểu ngầm, vì vậy có vẻ như nó có liên quan đến mặc định 'ContentTemplate' cho các đối tượng không phải là chuỗi –
Rachel