2014-10-16 196 views
0

我有這個非常小的測試應用程序,它探索WPF中的對象綁定。我對這個本地類的實例有約束力。 我正在探索綁定到xaml中的本地對象,在運行時設置數據上下文並在運行時修改資源實例。 我使用了窗口和應用資源,看看它們的影響,定義如下:WPF動態引用的應用程序資源在運行時不可更新

App.xaml中的資源

<local:MyData x:Key="myAppData" Info="App resource information" /> 
<local:MyData x:Key="myAppEmptyData" /> 
<local:MyData x:Key="myAppBogusData" Info="-" /> 

Window.xaml資源

<local:MyData x:Key="myWindowData" Info="Window resource information" /> 
<local:MyData x:Key="myWindowEmptyData" /> 

的我[App | Window] EmptyData有一個空信息成員,我試圖在運行時修改它。我正在窗口加載:

(this.Resources["myWindowEmptyData"] as MyData).Info = "window resource info set on runtime"; 
(Application.Current.Resources["myAppEmptyData"] as MyData).Info = "app resource info set on runtime"; 
(Application.Current.Resources["myAppBogusData"] as MyData).Info = "app resource info set on runtime"; 
this.lblDataContextSetAtRuntime.DataContext = new MyData() { Info = "data context set at runtime" }; 

下面主窗口的代碼。綠色標籤是預期的行爲。藍色標籤表示未修改的資源,但不希望被修改(靜態+窗口)。紅色標籤是意外的行爲。請參閱內嵌評論。

MainWindow.xaml

<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch" 
     DataContext="{StaticResource myWindowData}"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="1*" /><RowDefinition Height="1*" /><RowDefinition Height="1*" /><RowDefinition Height="1*" /><RowDefinition Height="1*" /><RowDefinition Height="1*" /><RowDefinition Height="1*" /><RowDefinition Height="1*" /> 
    </Grid.RowDefinitions> 
    <!--this uses data context from the grid--> 
    <Label Content="{Binding Path=Info}" Background="Green" Grid.Row="0" /> 
    <!--normal to not be updateable since window resources--> 
    <Label DataContext="{StaticResource myWindowEmptyData}" Content="{Binding Path=Info}" Background="CadetBlue" Grid.Row="1" x:Name="lblStaticWindowResource" /> 
    <Label DataContext="{DynamicResource myWindowEmptyData}" Content="{Binding Path=Info}" Background="CadetBlue" Grid.Row="2" x:Name="lblDynamicWindowResource" /> 
    <!--data context set at runtime--> 
    <Label Content="{Binding Path=Info}" Grid.Row="3" Background="Green" x:Name="lblDataContextSetAtRuntime" /> 
    <!--uses data context from app--> 
    <Label DataContext="{StaticResource myAppData}" Content="{Binding Path=Info}" Background="Green" Grid.Row="4" x:Name="lblAppData" /> 
    <!--static app resource not modifiable--> 
    <Label DataContext="{StaticResource myAppEmptyData}" Content="{Binding Path=Info}" Background="CadetBlue" Grid.Row="5" x:Name="lblStaticAppResource"/> 
    <!--DYNAMIC APP RESOURCE SHOULD GET MODIFIED--> 
    <Label DataContext="{DynamicResource myAppEmptyData}" Content="{Binding Path=Info}" Background="Red" Grid.Row="6" x:Name="lblDynamicEmptyAppResource" /> 
    <Label DataContext="{DynamicResource myAppBogusData}" Content="{Binding Path=Info}" Background="Red" Grid.Row="7" x:Name="lblDynamicBogusAppResource" /> 
    </Grid> 

即使在調試器窗口中的一個注意到的資源被修改 enter image description here

,在運行時有一個爲藍色和紅色的標籤,沒有內容。我認爲有空屬性的資源有問題,有點甚至myAppBogusData得到更新。

enter image description here

回答

1

MyData必須按順序執行INotifyPropertyChangedInfo財產通過結合更新。

class MyData : INotifyPropertyChanged 
{ 
    private string info; 
    public string Info 
    { 
     get { return info; } 
     set 
     { 
      if (info != value) 
      { 
       info = value; 
       RaisePropertyChanged("Info"); 
      } 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    private void RaisePropertyChanged(string propertyName) 
    { 
     var handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

除此之外,你不必使用DynamicResource - 一個StaticResource就足夠了。如果您需要完全更改MyData實例,則只需要使用DynamicResource。例如:

Application.Current.Resources["myAppBogusData"] = new MyData() { Info = "New data" }; 

如果你只是改變在給定的實例屬性,你可以使用StaticResource

+0

作品一種享受,謝謝。我的想法是不重新分配,只需修改屬性。 – 2014-10-17 09:41:27

相關問題