C# 基于视图模型中的属性更改更新UI
我是WPF的新手,所以这里可能缺少一些基本的东西。我有一个如下所示的应用程序:C# 基于视图模型中的属性更改更新UI,c#,.net,wpf,C#,.net,Wpf,我是WPF的新手,所以这里可能缺少一些基本的东西。我有一个如下所示的应用程序: <Window x:Class="MyApp.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Test Application" Height="647" W
<Window x:Class="MyApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test Application" Height="647" Width="723" Background="#88B0FF">
<DockPanel Name="MainDock">
<Button DockPanel.Dock="Top" Margin="5,0,5,0" x:Name="PingButton" Click="PingButton_OnClick">Ping</Button>
<TextBox Text="{Binding Path=Output}" />
</DockPanel>
</Window>
public partial class MainWindow : Window
{
private Model _applicationModel = new Model();
public Model ApplicationModel {
get { return _applicationModel; }
set { _applicationModel = value; }
}
public MainWindow()
{
InitializeComponent();
this.DataContext = ApplicationModel;
ApplicationModel.Output = "Not clicked";
}
private void PingButton_OnClick(object sender, RoutedEventArgs e)
{
ApplicationModel.Output = "Clicked";
}
}
private string output;
public string Output
{
get { return output; }
set { SetProperty(ref output, value); }
}
我有一个名为Model的小类,它实现了INotifyPropertyChanged
public class Model : INotifyPropertyChanged
{
public string Output { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
我运行此应用程序,文本框显示未单击的文本。当我点击按钮时,我希望文本会改变。事实并非如此。ApplicationModel对象被更新,这反映在DataContext中;然而,我在OnPropertyChanged方法中有一个断点,似乎从未调用过它
我做错了什么?没有调用OnPropertyChanged,因为您没有调用它。
没有什么特殊的魔法可以将调用连接到OnPropertyChanged本身,所以您需要自己完成
具体地说,您应该修改输出属性,以便在其发生更改时调用它,并且对ApplicationModel属性执行相同操作不会造成任何伤害:
private string output;
public string Output
{
get { return output; }
set
{
if (output != value)
{
output = value;
OnPropertyChanged("Output");
}
}
}
如果你的目标是.NET4.5,你可以利用减少样板代码;说明如何执行此操作。然后你会有这样的东西:
<Window x:Class="MyApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test Application" Height="647" Width="723" Background="#88B0FF">
<DockPanel Name="MainDock">
<Button DockPanel.Dock="Top" Margin="5,0,5,0" x:Name="PingButton" Click="PingButton_OnClick">Ping</Button>
<TextBox Text="{Binding Path=Output}" />
</DockPanel>
</Window>
public partial class MainWindow : Window
{
private Model _applicationModel = new Model();
public Model ApplicationModel {
get { return _applicationModel; }
set { _applicationModel = value; }
}
public MainWindow()
{
InitializeComponent();
this.DataContext = ApplicationModel;
ApplicationModel.Output = "Not clicked";
}
private void PingButton_OnClick(object sender, RoutedEventArgs e)
{
ApplicationModel.Output = "Clicked";
}
}
private string output;
public string Output
{
get { return output; }
set { SetProperty(ref output, value); }
}
如果您使用的是.NET 4.0或更低版本,您可以使用表达式树,如前所述。Bah,我希望这里有一些反射魔法。这里有减少样板文件的最佳实践吗?不喜欢[CallerMemberName],因为如果您需要通知与所调用的不同的属性,它将不起作用。代码最终将成为这两种方式的混合体。