2012-07-06 117 views
2

我有一個問題,讓我感到困惑。我正在學習我的MCP(測試70-511 Windows應用開發與.Net 4),我正在使用代碼中的資源和更改資源部分。這裏是直接從書報價(自進度培訓工具包):WPF 4資源

如果資源是指物體在代碼被更改,使用該資源的行爲不同,這取決於資源如何被引用的對象。在代碼中更改資源時,使用DynamicResource標記引用的資源使用新對象。使用StaticResource標記引用資源的對象繼續使用它們最初從資源中檢索到的對象,並且不知道此更改。

就這樣說,他們所要解決的問題之一就是XAML問題。下面是這個問題的代碼:

<Window x:Class="Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300"> 
    <Window.Resources> 
    <SolidColorBrush Color="Red" x:Key="ForegroundBrush" /> 
    <SolidColorBrush Color="Blue" x:Key="BackgroundBrush" /> 
    </Window.Resources> 
    <Grid> 
    <Button Background="{StaticResource BackgroundBrush}" 
     Foreground="{DynamicResource ForegroundBrush}" Height="23" 
     Margin="111,104,92,0" Name="Button1" 
     VerticalAlignment="Top">Button</Button> 
    </Grid> 
</Window> 

,問題是:執行下面的代碼時發生了按鈕的顏色是什麼?

SolidColorBrush aBrush = new SolidColorBrush(Colors.Green); 
this.Resources["ForegroundBrush"] = aBrush; 
SolidColorBrush bBrush; 
bBrush = (SolidColorBrush)this.Resources["BackgroundBrush"]; 
bBrush.Color = Colors.Black 

答案的選項:

  1. 沒有任何反應。
  2. 背景變黑。
  3. 前景變爲綠色。
  4. 均爲2和3

經書給出的答案是4或2和3

我的困境/困惑的是:如果這本書指出,動態資源將改變以反映在代碼中進行的更改以及靜態資源將繼續使用它們最初檢索的對象,那麼爲什麼上面的代碼/ XAML示例中按鈕的背景和前景都會更改?我已經嘗試過了,他們都改變了。

任何幫助,將不勝感激。

回答

1

讓我們把它切成了兩個部分:

1)這裏參考改變

SolidColorBrush aBrush = new SolidColorBrush(Colors.Green); 
this.Resources["ForegroundBrush"] = aBrush; 

2)這裏參考保持不變,但更改屬性(Color):

SolidColorBrush bBrush; 
bBrush = (SolidColorBrush)this.Resources["BackgroundBrush"]; 
bBrush.Color = Colors.Black 

記住t框架背後的帽子(WPF),還有像你或我可以寫的常規代碼。
你在這裏看到的行爲非常像ObservableCollections的行爲:

如果使用ObservableCollection作爲ItemsControlItemsSource,然後你做:

myBoundObsCollection = new ObservableCollection<object>(); 

結合不會刷新,除非你提出PropertyChanged

這裏是一個小樣本,測試到招行:

Mycol = new ObservableCollection<string>(); 

前/後InitializeComponent()在構造函數中,看看會發生什麼。

public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      this.DataContext = this; 
      Mycol = new ObservableCollection<string>(); 
      InitializeComponent(); 

      Mycol.Add("this"); 
      Mycol.Add("is"); 
      Mycol.Add("a"); 
      Mycol.Add("test"); 
     } 

     public ObservableCollection<string> Mycol { get; set; } 

     private void Button_Click(object sender, RoutedEventArgs e) 
     { 
      Mycol = new ObservableCollection<string>(); 
      Mycol.Add("??"); 
     } 
    } 

而XAML:

<Window x:Class="ObsColTest.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"> 
    <StackPanel> 
     <ListBox ItemsSource="{Binding Mycol}" /> 
     <Button Content="Click me!" Click="Button_Click"/> 
    </StackPanel> 
</Window> 

然後當你點擊按鈕,注意ListBox怎麼不更新,即使收集它必將徹底改變!

但如果你只是修改集合,新行會出現不管你提出的集合PropertyChanged與否。
也是一樣的SolidColorBrushColor財產。

DynamicResource解決了這個問題:在的事實,如果你更改資源的任何屬性,它會反映在UI上面,如果你改變了參考,它會反映在UI上也是如此。

請記住,它使DynamicResource(slightly?)比靜態資源少高性能;)