简体   繁体   English

为什么ListBox不绑定到IEnumerable更新?

[英]Why doesn't a ListBox bound to an IEnumerable update?

I have the following XAML: 我有以下XAML:

<Window x:Class="ListBoxTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:ListBoxTest"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:Model />
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <ListBox ItemsSource="{Binding Items}" Grid.Row="0"/>
        <Button Content="Add" Click="Button_Click" Grid.Row="1" Margin="5"/>
    </Grid>
</Window>

and the following code for the Model class, which is put into main window's DataContext : 以及以下Model类的代码,这些代码放入主窗口的DataContext

public class Model : INotifyPropertyChanged
{
    public Model()
    {
        items = new Dictionary<int, string>();
    }

    public void AddItem()
    {
        items.Add(items.Count, items.Count.ToString());

        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs("Items"));
    }

    private Dictionary<int, string> items;
    public IEnumerable<string> Items { get { return items.Values; } }

    public event PropertyChangedEventHandler PropertyChanged;
}

and main window's code: 和主窗口的代码:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var model = this.DataContext as Model;
        model.AddItem();
    }
}

When pressing the button, the contents of the list are not being updated. 按下按钮时,列表的内容不会被更新。

However, when I change the getter of the Items property to this: 但是,当我将Items属性的getter更改为此时:

public IEnumerable<string> Items { get { return items.Values.ToList(); } }

it starts to work. 它开始工作。

Then, when I comment out the part which sends PropertyChanged event it stops working again, which suggests that the event is being sent correctly. 然后,当我注释掉发送PropertyChanged事件的部分时,它将再次停止工作,这表明该事件已正确发送。

So if the list receives the event, why can't it update its contents correctly in the first version, without the ToList call? 因此,如果列表接收到该事件,为什么没有ToList调用就无法在第一个版本中正确更新其内容?

Raising the PropertyChanged event for the Items property is only effective if the property value has actually changed. 仅当属性值实际更改时,才Items属性的PropertyChanged事件。 While you raise the event, the WPF binding infrastructure notices that the collection instance returned by the property getter is the same as before and does nothing do update the binding target. 引发事件时,WPF绑定基础结构会注意到属性getter返回的集合实例与以前相同,并且不执行任何操作来更新绑定目标。

However, when you return items.Values.ToList() , a new collection instance is created each time, and the binding target is updated. 但是,当您返回items.Values.ToList() ,每次都会创建一个新的集合实例,并且更新绑定目标。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM