【问题标题】:Style Setter Freezing Brush样式设置器冷冻刷
【发布时间】:2012-02-10 22:02:29
【问题描述】:

我似乎遇到了一些与 WPF ResourceDictionaries、Brushes 和 Styles 相关的行为(至少到目前为止我注意到了这一点),这与我对这些事情应该如何工作的理解背道而驰。基本上,如果我从具有 ResourceDictionary 中的样式的 Setter 中引用画笔,则会导致画笔冻结。下面的示例说明了这一点,因为当我尝试在按钮的 Click 事件处理程序中更改共享画笔上的颜色时收到 InvalidOperationException。它应该导致两个 Rectangle 的颜色都发生变化,因为它们都使用相同的共享画笔,但我得到了异常。

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <SolidColorBrush x:Key="TestBrush" Color="Red" />
        <Style TargetType="Rectangle">
            <Setter Property="Fill" Value="{StaticResource TestBrush}" />
        </Style>
    </Window.Resources>
    <StackPanel>
        <Button Name="Button1" Content="Change Color" Click="Button1_Click" />
        <Rectangle Height="20" />
        <Rectangle Height="20" />
    </StackPanel>
</Window>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Button1_Click(object sender, RoutedEventArgs e)
    {
        var brush = (SolidColorBrush)FindResource("TestBrush");
        // InvalidOperationException Here.  Brush is Frozen/Read-Only
        brush.Color = Colors.Blue;
    }
}

如果我只是简单地删除样式(更具体地说是 Setter)并直接从每个 Rectangle 中引用 Brush(仍然来自 ResourceDictionary),我会从按钮单击事件中得到预期的 Rectangle 颜色变化行为。请参阅下面的代码(按钮单击事件处理程序保持不变)。

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <SolidColorBrush x:Key="TestBrush" Color="Red" />
    </Window.Resources>
    <StackPanel>
        <Button Name="Button1" Content="Change Color" Click="Button1_Click" />
        <Rectangle Height="20" Fill="{StaticResource TestBrush}" />
        <Rectangle Height="20" Fill="{StaticResource TestBrush}" />
    </StackPanel>
</Window>

我只看到 Brush 在从 Style 的 Setter 中被引用为 StaticResource 时才会冻结。我实际上可以从 ResourceDictionary 中的其他位置引用相同的 Brush 而不会冻结;即 ControlTemplates 的内容。

谁能解释一下这种奇怪的行为是怎么回事,是设计使然还是错误?

谢谢, 布兰登

【问题讨论】:

    标签: wpf xaml


    【解决方案1】:

    ...一旦应用了样式,它就会被密封并且无法更改。 如果你想动态改变一个已经被 应用时,您必须创建一种新样式来替换现有样式。为了 更多信息,请参阅 IsSealed 属性。

    http://msdn.microsoft.com/en-us/library/ms745683.aspx

    【讨论】:

    • 谢谢 Dmitry,但我并不想改变样式。我的问题是指画笔被冻结(IsFrozen = true)只是因为样式中存在一个将其称为静态资源的设置器。请注意(尽管我提到了这一点,但没有包括示例)我可以在样式中的其他位置使用画笔而不会冻结,只要它不在 Setter 内(即在 ControlTemplate 本身内)。跨度>
    • @Brandon 好吧,是的,我明白了。 WPF 在密封时冻结样式/模板可冻结值以提高性能和一些线程问题。到目前为止,我不知道如何防止(或撤销)这种情况的直接方法。
    猜你喜欢
    • 1970-01-01
    • 2016-04-05
    • 1970-01-01
    • 2021-12-01
    • 2016-04-10
    • 2016-03-14
    • 1970-01-01
    • 1970-01-01
    • 2020-06-08
    相关资源
    最近更新 更多