2017-05-08 93 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

相关问题