当绑定到引用保持不变的IEnumerable时,PropertyChanged被忽略

本文关键字:IEnumerable PropertyChanged 绑定 引用 | 更新日期: 2023-09-27 17:53:03

我创建了一个最小的示例来说明绑定问题。IEnumerable<string> NewReference按预期更新。IEnumerable<string> SameReference没有更新,可能是因为引用是相同的。Raise("SameReference");不足以使WPF更新参考

有什么可以做,使WPF框架重新评估SameReference,即使它有相同的参考?

xaml:

<Window x:Class="Stackoverflow.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid Background="Azure">
        <Grid.RowDefinitions>
            <RowDefinition Height="5*"/>
            <RowDefinition Height="1*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Button Content="Update" Margin="5" Grid.Row="1" Grid.ColumnSpan="2" Click="Button_Click" />
        <ListBox ItemsSource="{Binding SameReference}" Margin="5" />
        <ListBox ItemsSource="{Binding NewReference}" Margin="5" Grid.Column="1" />
    </Grid>
</Window>

xaml.cs:

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
namespace Stackoverflow
{
    public partial class MainWindow : Window , INotifyPropertyChanged
    {
        public List<string> data = new List<string> {  };
        public IEnumerable<string> SameReference { get { return data; } } //this returns a reference to an unchanged object
        public IEnumerable<string> NewReference { get { return new List<string>(data); } } //this returns a reference to a new object
        //ObservableCollection<string> conventional is known but not the point of this question
        public event PropertyChangedEventHandler PropertyChanged;
        private void Raise(string propertyName)
        {
            if(null != PropertyChanged)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        public MainWindow()
        {
            this.DataContext = this;
            InitializeComponent();
        }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            data.Add("This is data.");
            Raise("SameReference"); //successful notify, ignored values
            Raise("NewReference"); //successful notify, processed values
        }
    }
}

当绑定到引用保持不变的IEnumerable时,PropertyChanged被忽略

这是有意的行为。如果你想让集合更新实现INotifyCollectionChanged(或使用一个已经这样做的类,如ObservableCollection<T>)。