我的属性更新很好,但我的用户界面没有更新。 我究竟做错了什么?
我也试过设置DataContext
不在XAML中,但是在构造函数后面的代码中,但是它也没有用。
视图模型:
public class MainWindowViewModel : INotifyPropertyChanged
{
public MainWindowViewModel()
{
TestCommand = new RelayCommand(UpdateTest);
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
if (PropertyChanged != null)
PropertyChanged(null, new PropertyChangedEventArgs(propertyName));
}
#endregion
private string _test;
public string Test
{
get { return _test; }
set
{
_test = value;
NotifyPropertyChanged();
}
}
public ICommand TestCommand { get; set; }
public void UpdateTest()
{
Test += "test ";
}
}
查看:
<Window x:Class="Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Test"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Text="{Binding Test}" />
<Button Grid.Row="1" Content="Test 2" Command="{Binding TestCommand}" />
</Grid>
</Window>
答案 0 :(得分:3)
您没有正确实施PropertyChanged
。 .NET的事件模型要求将调用的委托的sender
参数设置为实际引发事件的对象的引用。您将该值设置为null
。您的代码应使用this
代替:
protected void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
请注意,对于线程安全性,您还应该不在事件字段本身上使用“检查和提升”模式。您应该将字段存储在局部变量中,检查局部变量,然后如果非null则从该变量引发事件。以上使用?.
运算符(“空条件运算符”)有效地做到了这一点;编译器会为您隐式生成局部变量,并确保在您为null
检查它的时间与实际尝试使用它的时间之间不会改变引用。