【问题标题】:ListView not updating on the itemsource ObservableCollection Item Property changeListView 未更新 itemsource ObservableCollection 项目属性更改
【发布时间】:2015-01-27 11:53:39
【问题描述】:

考虑以下示例代码:

视图.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

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

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)
        {

        }
    }
}

模型.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)
        {

        }
    }
}

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

例如: 单击上面指定的按钮时
一种。添加一个新项目(成功反映在 ListView 中)
湾。修改第一项的 FirstName(不反映在 ListView 中)

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

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

【问题讨论】:

  • 是简化代码版本还是你真的没有在OnPropertyChanged 方法中引发INPC.PropertyChanged 事件?你得到了处理程序,但你没有引发事件:handler(this, new PropertyChangedEventArgs(name));

标签: c# wpf mvvm data-binding


【解决方案1】:

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

here

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

NotifyCollectionChangedAction.Reset

重置它们的事件

here

【讨论】:

  • 我已阅读该链接并同样实施但没有成功并再次重新检查。调试时发现它没有进入EntityViewModelPropertyChanged()。我应该发布代码吗?
  • 确定item.PropertyChanged += EntityViewModelPropertyChanged;为每个项目调用。您可以发布您的代码。
  • 发布了代码。 item.PropertyChanged += EntityViewModelPropertyChanged 为 ObservableCollection 中的每个全名项调用。但是在进行更改时,控件不会转到 EntityViewModelPropertyChanged。
  • 这是你的真实代码吗?你看到 dkozl 的评论了吗?
  • 这很尴尬。没有引发事件。真的很抱歉浪费你的时间。也非常感谢@dkozl
【解决方案2】:

我也在 WinUI 上使用ListViewObservableCollection 解决同样的问题。

你需要了解的是ObservableCollection只负责通知集合的变化。项目级别更改通过INotifyPropertyChanged 处理。但是,对于要应用的那些,您需要确保您的绑定模式至少是一种方式,如果需要,可以使用两种方式。

您的 XAML 应如下所示: Text="{x:Bind Title, Mode=OneWay}

不要尝试那里的建议,这是错误的: ObservableCollection not noticing when Item in it changes (even with INotifyPropertyChanged)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-25
    • 2017-11-19
    • 1970-01-01
    • 2014-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多