【发布时间】: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 的内容。
谁能解释一下这种奇怪的行为是怎么回事,是设计使然还是错误?
谢谢, 布兰登
【问题讨论】: