2012-02-10 52 views
1

我似乎遇到了一些關於WPF ResourceDictionaries,Brushes和Styles的行爲(至少這是我迄今注意到的),這與我對這些事情應該如何工作的理解相反。基本上,如果我使用ResourceDictionary中的樣式引用Setter中的Brush,它將導致Brush被凍結。下面的例子說明了這一點,因爲當我嘗試在我的按鈕的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; 
    } 
} 

如果我只是直接從每個矩形刪除樣式(更具體的二傳手)和(從資源字典仍然)引用刷,我得到的矩形的顏色的預期行爲串聯改變從按鈕點擊事件。請參閱下面的代碼(按鈕點擊事件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> 

我只看到刷子被引用爲Style的Setter中的StaticResource時變爲凍結。我可以有效地從ResourceDictionary中的其他位置引用相同的Brush,而不會凍結它;即ControlTemplates的內容。

任何人都可以請解釋這個奇怪的行爲是怎麼回事,如果它是通過設計或錯誤?

感謝, 布蘭登

回答

1

...一旦風格得到了應用,它是密封的,不能改變。 如果您想動態更改已應用 的樣式,則必須創建一個新樣式來替換現有樣式。有關 的更多信息,請參閱IsSealed屬性。

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

+0

謝謝德米特里,但我並不想改變風格。我的問題是指畫筆變得凍結(IsFrozen = true),只需在樣式中存在一個Setter,將其引用爲StaticResource。請注意(雖然我提到了這一點,但沒有包括一個例子),我可以在Style中的其他地方有效地使用畫筆,只要它不在Setter內(即在ControlTemplate本身內),它就不會凍結。 – Brandon 2012-02-13 14:15:01

+0

@布朗恩,好的,我明白了。 WPF在密封時凍結樣式/模板凍結值以提高性能和一些線程問題。我不知道迄今爲止如何防止(或撤消)的直接方式。 – 2012-02-14 01:33:11