2017-05-08 85 views
1

爲什麼上升INotifypPropertyChangedList<T>屬性不起作用?爲什麼通知列表<T>屬性不起作用

考慮這個MCVE:

public class NotifyPropertyChanged : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
    public void OnPropertyChanged([CallerMemberName] string property = "") => 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property)); 
} 

public class TextWrapper 
{ 
    public string Text { get; set; } 
    public override string ToString() => Text; 
} 

public class ViewModel : NotifyPropertyChanged 
{ 
    public List<string> List { get; } = new List<string>(); 
    public TextWrapper Text { get; } = new TextWrapper(); 

    public void AddToList(string text) 
    { 
     List.Add(text); 
     OnPropertyChanged(nameof(List)); 
    } 

    public void ChangeText(string text) 
    { 
     Text.Text = text; 
     OnPropertyChanged(nameof(Text)); 
    } 
} 

public partial class MainWindow : Window 
{ 
    readonly ViewModel _vm = new ViewModel(); 

    public MainWindow() 
    { 
     InitializeComponent(); 
     DataContext = _vm; 
    } 
} 

XAML:

<TextBlock Text="{Binding Text}" /> 
<ListBox ItemsSource="{Binding List}" /> 

調用_vm.ChangeText(...)將正確地更新TextBlock,同時呼籲_vm.AddToList(...)不更新ListBox(它會一直爲空)。爲什麼?

請注意:我知道ObservableCollection<T>,我知道大約兩個可能的解決方法(添加二傳手到List並將其設置爲例如null先升後回或更換DataContext/ItemsSource)。我只是好奇什麼在屋頂下使List<T>TextWrapper更特別。

+0

附註 - 不確定是否可能導致問題,但List是保留名稱。嘗試改變它或用「@」作爲前綴,如「@ List」。 –

+0

@KamilSolecki用某個類的名字命名一個屬性是完全合法的。還要注意''List'是一個_generic_類,所以它的名字從來就不是簡單的「List」,而是「List'1」等。 –

回答

3

當WPF綁定處理PropertyChanged事件時,它不會更新其目標屬性,除非其生成的有效值實際發生了更改。

所以除非List屬性值實際上改變(這不,當你添加元素),調用

OnPropertyChanged(nameof(List)); 

沒有效果。

更換

public List<string> List { get; } = new List<string>(); 

通過

public ObservableCollection<string> List { get; } = new ObservableCollection<string>(); 

,寫AddToList方法是這樣的:

public void AddToList(string text) 
{ 
    List.Add(text); 
} 

爲了您TextWrapper類:既然你直接綁定到TextWrapper instanc e,綁定調用其覆蓋的ToString()方法,並因此在TextWrapper的Text屬性發生更改時產生不同的值。

+0

爲什麼要爲'Text'調用它? – Sinatr

+0

而且?這兩個屬性的實例仍然存在。我不明白。它與某種比較器或什麼有關?請注意,我不是要求解決方案(我的問題的最後一段),我的問題主要是關於'Text'和'List'行爲('ViewModel'的屬性)的區別。 – Sinatr

+0

'ViewModel.Text'的值不變,只有'TextWrapper.Text'(並且'TextWrapper'內沒有通知)。 – Sinatr

相關問題