TextBlock 的重写样式的奇怪行为

Posted

技术标签:

【中文标题】TextBlock 的重写样式的奇怪行为【英文标题】:Strange behaviour of overridden Style of TextBlock 【发布时间】:2012-06-13 09:09:34 【问题描述】:

几天前,我遇到了 Button 中文本的奇怪行为(我猜其他 ContentControl 也会遇到同样的行为)。让我解释一下情况。我在 App.xaml 中有一个 TextBlock 的样式定义:

<Application.Resources>
    <Style TargetType="x:Type TextBlock">
        <Setter Property="Margin" Value="10"/>
    </Style>
</Application.Resources>

在 MainWindow.xaml 中我有相同的样式定义,它应该覆盖在 App.xaml 中定义的样式。我在 Window 中也有 3 个按钮。在第一个按钮中,在按钮内容中明确定义了 TextBlock 控件。对于第二个按钮,我将字符串设置为代码隐藏中的内容。对于第三个按钮,我将一个整数值设置为代码隐藏中的内容。这是 MainWindow.xaml 的代码:

<StackPanel>
    <StackPanel.Resources>
        <Style TargetType="x:Type TextBlock">
            <Setter Property="Margin" Value="0"/>
        </Style>
    </StackPanel.Resources>
    <Button Name="Button1">
        <Button.Content>
            <TextBlock Text="Button with text block"/>
        </Button.Content>
    </Button>
    <Button Name="Button2" />
    <Button Name="Button3" />
</StackPanel>

和 MainWindow.xaml.cs:

private void Window_Loaded(object sender, RoutedEventArgs e)

    Button2.Content = "Button with string";
    Button3.Content = 16;

现在我们看到了什么?正如预期的那样,第一个和第三个按钮中的文本有 0 像素的边距,但第二个按钮中的文本有 10 像素的边距!问题是:为什么第二个按钮有 10px 的边距以及如何为第二个按钮设置零边距(从 App.xaml 中删除样式是不可能的)?

谢谢!

【问题讨论】:

snoop 揭示了什么? 我已经尝试过您的代码:Snoop 说第二个 TextBlock 的 Margin=10,而其他 TextBlock 的 Margin=0。在所有三种情况下,值源都是一种样式。目前,我不知道是什么导致了这种差异。 【参考方案1】:

当我改变时

Button2.Content = "Button with string"; 

Button2.Content = "Button with _string"; 

按钮的边距从 10 变为 0。

这是 WPF 中的一个错误;已经在Microsoft Connect上报告了。

我不是 100% 确定,但我认为您看到的行为是由相同的根本原因造成的。

顺便说一句:正确的行为是按钮 2 和 3 的 Margin=10;这是因为资源查找是沿着逻辑树而不是可视树执行的。按钮 2 和 3 中的 TextBlock 不在 StackPanel 的逻辑树中。

【讨论】:

【参考方案2】:

我不能给你一个明确的答案,但我注意到设置字符串和整数之间的区别会导致应用不同的样式。

由于将 Content 设置为需要转换的值会导致应用正确的样式,因此我尝试了以下操作:

private void WindowLoaded(object sender, RoutedEventArgs e)

    Button2.Content = new TextHolder("Button with string");
    Button3.Content = 16;


public class TextHolder

    private readonly string _text;

    public TextHolder(string text)
    
        _text = text;
    

    public override string ToString()
    
        return _text;
    

现在边距为 0。我很想了解到底发生了什么。

【讨论】:

以上是关于TextBlock 的重写样式的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章

如何根据条件为单元格正确分配样式,而不会在快速滚动后出现奇怪的样式行为?

如何纠正 Pandas 样式数据框中的奇怪行为

设置TextBlock默认样式后,其他控件的Text相关属性设置失效问题

WPF 定义了TextBlock样式后,其他控件的样式都改变了

设置TextBlock默认样式后,其他控件的Text相关属性设置失效问题

TextBlock 样式覆盖模板化父样式