使用SetProperty

时间:2017-10-25 16:07:28

标签: c# wpf list prism inotifypropertychanged

我的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不起作用?

我不理解正确的事情吗?

1 个答案:

答案 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}}。但它确实如此。