2017-10-20 82 views
1

我的属性更新很好,但我的用户界面没有更新。 我在做什么错?UI未更新绑定元素

我也尝试设置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> 

回答

3

您没有正确地实现PropertyChanged。 .NET的事件模型要求调用委托的参数sender设置为实际引发事件的对象的引用。您将该值设置为null。你的代码应该使用this代替:

protected void NotifyPropertyChanged([CallerMemberName] string propertyName = null) 
{ 
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
} 

需要注意的是线程安全,你应该也不能使用“检查,提高”的格局对事件字段本身。您应该将该字段存储在局部变量中,检查局部变量,然后如果非空,则从该变量中引发该事件。以上使用?.运算符(“空条件运算符”)有效地执行此操作;编译器会为您隐式生成本地变量,并确保在您检查null的时间与实际尝试使用它的时间之间,引用不会发生变化。

+0

谢谢,这的确有窍门。不能相信我错过了:) – Patrick