Я, кажется, столкнулся с некоторым поведением в отношении WPF ResourceDictionaries, Brushes и Styles (по крайней мере, это то, что я заметил до сих пор), что противоречит моему пониманию того, как эти вещи должны работать. В принципе, если я ссылаюсь на кисть из сеттера с стилем в ResourceDictionary, он заставляет кисть замораживаться. Пример ниже иллюстрирует это, так как я получаю InvalidOperationException, когда я пытаюсь изменить цвет в общей кисти в обработчике события Click моей кнопки. Это должно привести к изменению цвета Rectangle, поскольку оба они используют один и тот же общий Brush, но вместо этого я получаю исключение.Style Setter Freezing 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;
}
}
Если я просто удалить стиль (более конкретно сеттер) и ссылки на кисти (до сих пор от ResourceDictionary) непосредственно из каждого прямоугольника, я получаю ожидаемое поведение цветов прямоугольников меняется в тандеме из события нажатия кнопки. См. Код ниже (кнопка click event 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>
Я только вижу кисть становится замороженной, когда он упоминается как StaticResource из сеттер стиля, в. Я могу actaully ссылаться на тот же Brush из других мест в ResourceDictionary, не замораживая; т.е. содержимое ControlTemplates.
Может кто-нибудь объяснить, что происходит с этим странным поведением, и если это по дизайну или ошибка?
Спасибо, Brandon
Спасибо Дмитрию, но я не пытаюсь изменить стиль. Мой вопрос относится к тому, что кисть становится замороженной (IsFrozen = true) просто наличием сеттера в стиле, который ссылается на него как на StaticResource. Обратите внимание, что (хотя я упоминаю об этом, но не включил пример), я могу использовать кисть в других местах в стиле, не замораживая ее, пока она не находится в Setter (то есть внутри самой ControlTemplate). – Brandon
@ Браун хорошо, да, я вижу. WPF замораживает значения замораживания стилей/шаблонов при печати, чтобы повысить производительность и некоторые проблемы с потоками. Я не знаю прямых путей того, как это можно предотвратить (или отменить) до сих пор. –