WPF,为什么将PropertyChanged 添加到List<> 没有生效?
WPF, why adding PropertyChanged to List<> does not take into effect?
为什么 PropertyChangedEvent 可以添加到 String 属性,但不能添加到 List<> 属性?
xaml 喜欢这个:
<StackPanel>
<ListBox ItemsSource="{Binding Items}" Height="300"/>
<Button Click="Button_Click">Change</Button>
</StackPanel>
和 xaml.cs 这样的:
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
//public ObservableCollection<String> Items { get; set; } = new ObservableCollection<String>(); // ok
public List<String> Items // no effect
{
get { return _items; }
set
{
_items = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Items"));
}
}
private List<String> _items = new List<string>();
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
Items.Add("aaa");
Items.Add("bbb");
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Items.Clear();
for (int i = 0; i < 5; i++)
Items.Add(i.ToString());
}
}
您的问题可以通过多种方式解决,
点击按钮创建另一个列表,示例代码如下
使用 Observable 集合
改变
private RelayCommand _buttonClick;
public RelayCommand ButtonClick => _buttonClick ?? new RelayCommand(onButtonClick, canButtonClick);
private bool canButtonClick(object obj)
{
return true;
}
private void onButtonClick(object obj)
{
List<String> tempItems = new List<string>();
for (int i = 0; i < 5; i++)
tempItems.Add(i.ToString());
Items = tempItems;
}
它不起作用,因为您只在设置整个列表时通知,而不是在列表中添加或删除项目时通知。
使用 ObservableCollection<string>
而不是 List<string>
:
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private ObservableCollection<string> _Items = new ObservableCollection<string>();
public ObservableCollection<string> Items
{
get { return _Items; }
set
{
_Items = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Items));
}
}
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
Items.Add("aaa");
Items.Add("bbb");
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Items.Clear();
for (int i = 0; i < 5; i++)
Items.Add(i.ToString());
}
}
为什么 PropertyChangedEvent 可以添加到 String 属性,但不能添加到 List<> 属性?
xaml 喜欢这个:
<StackPanel>
<ListBox ItemsSource="{Binding Items}" Height="300"/>
<Button Click="Button_Click">Change</Button>
</StackPanel>
和 xaml.cs 这样的:
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
//public ObservableCollection<String> Items { get; set; } = new ObservableCollection<String>(); // ok
public List<String> Items // no effect
{
get { return _items; }
set
{
_items = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Items"));
}
}
private List<String> _items = new List<string>();
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
Items.Add("aaa");
Items.Add("bbb");
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Items.Clear();
for (int i = 0; i < 5; i++)
Items.Add(i.ToString());
}
}
您的问题可以通过多种方式解决,
点击按钮创建另一个列表,示例代码如下
使用 Observable 集合
改变private RelayCommand _buttonClick; public RelayCommand ButtonClick => _buttonClick ?? new RelayCommand(onButtonClick, canButtonClick); private bool canButtonClick(object obj) { return true; } private void onButtonClick(object obj) { List<String> tempItems = new List<string>(); for (int i = 0; i < 5; i++) tempItems.Add(i.ToString()); Items = tempItems; }
它不起作用,因为您只在设置整个列表时通知,而不是在列表中添加或删除项目时通知。
使用 ObservableCollection<string>
而不是 List<string>
:
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private ObservableCollection<string> _Items = new ObservableCollection<string>();
public ObservableCollection<string> Items
{
get { return _Items; }
set
{
_Items = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Items));
}
}
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
Items.Add("aaa");
Items.Add("bbb");
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Items.Clear();
for (int i = 0; i < 5; i++)
Items.Add(i.ToString());
}
}