Style Setter 冻结刷 [英] Style Setter Freezing Brush

查看:18
本文介绍了Style Setter 冻结刷的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I seem to have run into some behavior regarding WPF ResourceDictionaries, Brushes, and Styles (at least that's what I've noticed so far) that is counter to my understanding of how these things should work. Basically, if I reference a Brush from a Setter withing a Style in a ResourceDictionary it causes the Brush to become frozen. The example below illustrates this, as I get an InvalidOperationException when I try to change the Color on the shared Brush within my button's Click event handler. It should cause both Rectangle's color to change, as they both use the same shared Brush, but I get the exception instead.

<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)并直接从每个矩形引用画笔(仍然来自 ResourceDictionary),我会从按钮单击事件中获得矩形颜色的预期行为.请参阅下面的代码(按钮单击事件处理程序保持不变).

If I simply remove the Style (more specifically the Setter) and reference the Brush (still from the ResourceDictionary) directly from each Rectangle, I get the expected behavior of the Rectangles' colors changing in tandem from the button click event. See code below (button click event hanlder remains the same).

<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 在被样式的 Setter 引用为 StaticResource 时被冻结.我实际上可以从 ResourceDictionary 中的其他位置引用相同的 Brush,而不会被冻结;即 ControlTemplates 的内容.

I only see the Brush becoming frozen when it is referenced as a StaticResource from a Style's Setter. I can actaully reference the same Brush from other locations within the ResourceDictionary without it becoming frozen; i.e. the contents of ControlTemplates.

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

Can anyone please explain what is going on with this strange behavior and if it's by-design or a bug?

谢谢,布兰登

推荐答案

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

...once a style has been applied, it is sealed and cannot be changed. If you want to dynamically change a style that has already been applied, you must create a new style to replace the existing one. For more information, see the IsSealed property.

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

这篇关于Style Setter 冻结刷的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆