我似乎遇到了一些关于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的内容。
任何人都可以解释一下这种奇怪的行为是什么,如果是设计还是错误?
谢谢, 布兰登
答案 0 :(得分:1)
...一旦应用了一种风格,它就会被密封并且无法更改。 如果要动态更改已经存在的样式 应用后,您必须创建一个新样式来替换现有样式。对于 有关更多信息,请参阅IsSealed属性。