我有一个非常小的测试应用程序,它探索了WPF中的对象绑定。我绑定到这个class MyData { public string Info { get; set; } }
本地类的实例。
我正在探索绑定到xaml中的本地对象,在运行时设置数据上下文以及在运行时修改资源实例。
我正在使用窗口和应用程序资源来查看它们的影响,如下所示:
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有一个null信息成员,我试图在运行时修改它。我在窗口加载时这样做:
(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>
即使在调试器窗口中,也注意到资源已被修改
,在运行时,蓝色和红色标签没有内容。我认为使用null属性的资源存在问题,甚至没有更新myAppBogusData。
答案 0 :(得分:1)
MyData
必须实施INotifyPropertyChanged
才能通过绑定更新Info
属性。
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
即可。如果您需要完全更改DynamicResource
实例,则只需使用MyData
。例如:
Application.Current.Resources["myAppBogusData"] = new MyData() { Info = "New data" };
如果您只是更改给定实例的属性,则可以使用StaticResource
。