我的MainWindow上有一个带有以下XAML
的ListBox<Window x:Class="MVVMExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MVVMExample"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ListBox x:Name="listBox" HorizontalAlignment="Left" Height="241" Margin="24,48,0,0" VerticalAlignment="Top" Width="150" ItemsSource="{Binding Items}"/>
<Label x:Name="label" Content="Items" HorizontalAlignment="Left" Margin="24,17,0,0" VerticalAlignment="Top"/>
<Button x:Name="button" Content="Add Item" HorizontalAlignment="Left" Margin="194,140,0,0" VerticalAlignment="Top" Width="75" Command="{Binding AddItemCommand}"/>
</Grid>
</Window>
我有我的MainWindowViewModel
using Prism.Commands;
using Prism.Mvvm;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Input;
namespace MVVMExample
{
public class MainWindowViewModel : BindableBase
{
public ICommand AddItemCommand { get; set; }
private List<string> items;
public List<string> Items
{
get { return items; }
set { SetProperty(ref items, value); }
}
public MainWindowViewModel()
{
Items = new List<string>();
Items.Add("Item 1");
AddItemCommand = new DelegateCommand(ExecuteAddItem);
}
private void ExecuteAddItem()
{
Items.Add("Item 2");
}
}
}
据我所知,每当属性发生变化时,SetProperty方法都会引发INotifyPropertyChanged事件。
每当我运行这个程序时,我都能看到MainWindow上的ListBox确实有项目&#34;项目1&#34;但是当我按下Add Item按钮时,项目&#34; Item 2&#34;虽然它已添加到“项目”列表中,但不会添加到UI中。
我知道如果我使用ObservableCollection而不是List我可以得到&#34; Item 2&#34;要添加到ListBox。但是,如果我使用SetProperty方法,为什么使用List不起作用?
我不理解正确的事情吗?
答案 0 :(得分:1)
当您为属性分配新列表时,您为List<string>
提出的唯一通知是在setter中。此代码不会将新Items
实例分配给Items
。它调用Items.Add("Item 2");
的getter并在列表中添加一个字符串。不会引发任何通知事件,因为您从不执行任何引发通知事件的代码。
get
这是您的get { return items; }
区块:
List<String>.Add()
它不会引发任何事件。无论如何,它在List<String>.Add()
之前被调用。怎么知道你计划做的下一件事是将一个项目添加到列表中?也许你只是在列举它。如果确实知道,在添加项目之前提升事件是什么用途?
ObservableCollection<String>
也不会引发任何事件。
如果您希望在向集合中添加项目时通知UI,请使用ObservableCollection<T>
。这就是ObservableCollection<T>
存在的原因:因此,当您添加或删除项目时,会有一个集合通知用户界面。如果只是模糊地接近引发事件的代码就足够了,那么就不需要{{1}}。但它确实如此。