为什么 ListBox 不绑定到 IEnumerable 更新? [英] Why doesn't a ListBox bound to an IEnumerable update?

查看:29
本文介绍了为什么 ListBox 不绑定到 IEnumerable 更新?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下 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>

以及Model类的以下代码,该类放入主窗口的DataContext:

and the following code for the Model class, which is put into main window's 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;
}

和主窗口的代码:

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.

但是,当我将 Items 属性的 getter 更改为:

However, when I change the getter of the Items property to this:

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

它开始工作.

然后,当我注释掉发送 PropertyChanged 事件的部分时,它再次停止工作,这表明该事件正在正确发送.

Then, when I comment out the part which sends PropertyChanged event it stops working again, which suggests that the event is being sent correctly.

那么如果列表接收到事件,为什么它不能在没有ToList调用的情况下在第一个版本中正确更新其内容?

So if the list receives the event, why can't it update its contents correctly in the first version, without the ToList call?

推荐答案

引发 Items 属性的 PropertyChanged 事件仅在属性值实际更改时才有效.当您引发事件时,WPF 绑定基础结构会注意到属性 getter 返回的集合实例与之前相同,并且不会更新绑定目标.

Raising the PropertyChanged event for the Items property is only effective if the property value has actually changed. 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.

但是,当您返回items.Values.ToList()时,每次都会创建一个新的集合实例,并更新绑定目标.

However, when you return items.Values.ToList(), a new collection instance is created each time, and the binding target is updated.

这篇关于为什么 ListBox 不绑定到 IEnumerable 更新?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆