Style Setter冷冻刷

时间:2012-02-10 22:02:30

标签: wpf xaml

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

<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;
    }
}

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

<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的内容。

任何人都可以解释一下这种奇怪的行为是什么,如果是设计还是错误?

谢谢, 布兰登

1 个答案:

答案 0 :(得分:1)

  

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

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