wpf ListView 未在 itemsource ObservableCollection Item 属性更改上更新

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28169880/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 12:53:01  来源:igfitidea点击:

ListView not updating on the itemsource ObservableCollection Item Property change

c#wpfmvvmdata-binding

提问by Parshuram

Consider the following Sample Code :

考虑以下示例代码:

View.xml

视图文件

<Grid>
    <ListView Name="NameList" HorizontalAlignment="Left" Height="142" Margin="55,45,0,0" VerticalAlignment="Top" Width="389">
        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>
                    <Label Content="{Binding FirstName}"/>
                    <Label Content="{Binding LastName}" Grid.Column="1"/>
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
    <Button Content="Button" HorizontalAlignment="Left" Margin="120,256,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>

</Grid>

View.xml.cs

查看.xml.cs

public partial class MainWindow : Window
{
    ViewModel vm;
    public MainWindow()
    {
        InitializeComponent();
        vm = new ViewModel();
        this.DataContext = vm;
        NameList.ItemsSource = vm.fn;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        vm.fn.Add(new fullname("P", "Q"));
        vm.fn[0].FirstName = "NewName";
    }

}

ViewModel.cs

视图模型.cs

class ViewModel : INotifyPropertyChanged
{

    public ViewModel()
    {
        fn = new ObservableCollection<fullname>();
        fn.CollectionChanged += ContentCollectionChanged;
        fn.Add(new fullname("A", "B"));
        fn.Add(new fullname("C", "D"));
    }

    public void ContentCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Remove)
        {
            foreach (fullname item in e.OldItems)
            {
                //Removed items
                item.PropertyChanged -= EntityViewModelPropertyChanged;
            }
        }
        else if (e.Action == NotifyCollectionChangedAction.Add)
        {
            foreach (fullname item in e.NewItems)
            {
                //Added items
                item.PropertyChanged += EntityViewModelPropertyChanged;
            }
        }
    }

    public void EntityViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        //This will get called when the property of an object inside the collection changes
    }

    public ObservableCollection<fullname> _fn;
    public ObservableCollection<fullname> fn
    {
        get { return _fn; }
        set { _fn = value; OnPropertyChanged("fn"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {

        }
    }
}

Model.cs

模型.cs

class fullname : INotifyPropertyChanged
{
    public fullname(string f, string l)
    {
        FirstName = f;
        LastName = l;
    }

    public string _FirstName;
    public string FirstName
    {
        get { return _FirstName; }
        set { _FirstName = value; OnPropertyChanged("FirstName"); }
    }


    public string _LastName;
    public string LastName
    {
        get { return _LastName; }
        set { _LastName = value; OnPropertyChanged("LastName"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {

        }
    }
}

If I add or remove any items in the ObservableCollection it updates the ListView in the View correctly but the problem is that if i modify the ObservableCollection item property the ListView is not updated.

如果我添加或删除 ObservableCollection 中的任何项目,它会正确更新视图中的 ListView,但问题是如果我修改 ObservableCollection 项目属性,则不会更新 ListView。

for ex: On click of above specified button it
a. Adds a new item (Successfully reflected in the ListView)
b. Modify FirstName of first item (Not reflected in the ListView)

例如:单击上面指定的按钮即可
。添加一个新项目(成功反映在 ListView 中)
b. 修改第一项的名字(在ListView中没有体现)

What should i do so as to make the modifications reflect in View.

我应该怎么做才能使修改反映在 View 中。

I would be very thankful if anyone could point out what i am doing wrong.

如果有人能指出我做错了什么,我将不胜感激。

回答by Eric Bole-Feysot

ObservableCollection event are not fired when an item is changed, only when it is added, removed or moved. You must implement INotifyPropertyChanged interface in item class, and register each item event in collection.

ObservableCollection 事件不会在项目更改时触发,只有在添加、删除或移动时才会触发。您必须在项目类中实现 INotifyPropertyChanged 接口,并在集合中注册每个项目事件。

See here

这里

If you make heavy changes in the collection, you can raise a

如果您对集合进行了重大更改,则可以提出一个

NotifyCollectionChangedAction.Reset

NotifyCollectionChangedAction.Reset

event to reset them all

将它们全部重置的事件

See here

这里