2017-10-20 81 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