的ObservableCollection< T>在listView中显示重复(多个)值 [英] ObservableCollection<T> show duplicated (multiple) value in a listView

查看:78
本文介绍了的ObservableCollection< T>在listView中显示重复(多个)值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了以下代码,用于在可观察集合中添加的某个项目更改属性时触发事件。每次添加或修改某个项目时,集合都会正确更新。我在Form Class中订阅了CollectionChanged事件,这些值在listView中更新但有几次(它们是重复的,有时是重复的,有时是正确的数字)。为了更好地解释:如果更新了12个项目,有时我可以在列表视图中看到12个项目,有时是19个,依此类推。有什么问题?



Hi, i wrote the following code to fire an event when some item, added in the observable collection, change property. Every time some item is added or modified the collection is rightly update. I subscribe the CollectionChanged event in the Form Class, the values are update in the listView but several time (they are duplicate, sometimes triplicate, sometimes in the right number). To explain better: if 12 items are update, sometimes i can see 12 item in the list view, sometimes 19, and so on. What's the problem?

public class ChangedItems_ObsCollection<T> : ObservableCollection<T> where T: INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler ItemPropertyChanged;
	//CONSTRUCTOR
        public ChangedItems_ObsCollection()
            : base()
        {
           CollectionChanged += new NotifyCollectionChangedEventHandler(ItemsObservableCollection_CollectionChanged);
        }
	//CONSTRUCTOR
        public ChangedItems_ObsCollection(List<T> list)
            : base(list)
        {
            foreach (var tag in list)
            {
                this.Add(tag);
                CollectionChanged += new NotifyCollectionChangedEventHandler(ItemsObservableCollection_CollectionChanged);
            }
            
        }

        private void ItemsObservableCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.NewItems != null)
            {
                foreach (Object item in e.NewItems)
                {
                    (item as INotifyPropertyChanged).PropertyChanged += new PropertyChangedEventHandler(Item_PropertyChanged);
                }
                IList recentList = e.NewItems;
            }
            if (e.OldItems != null)
            {
                foreach (Object item in e.OldItems)
                {
                    (item as INotifyPropertyChanged).PropertyChanged -= new PropertyChangedEventHandler(Item_PropertyChanged);
                }
            }
        }

        private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            NotifyCollectionChangedEventArgs reset = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset);
            OnCollectionChanged(reset);
            if (ItemPropertyChanged != null)
            {
                ItemPropertyChanged(sender, e);
            }
        }

    }
}







public partial class Form1 : Form
    {
        private MyClass myCollection = new MyClass();

        public Form1()
        {
            InitializeComponent();
            myCollection.TestCollection.CollectionChanged += MyCollection_CollectionChanged;           
        }

        private void MyCollection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
                this.UIThread(() => listView1.Items.Clear());
                int   i = 0;

                foreach (var tag in myCollection.TestCollection )
                {
                    ListViewItem item = new ListViewItem(i.ToString());
                    item.SubItems.Add(tag.Nome);
                    item.SubItems.Add(tag.Valore.ToString());
                    this.UIThread(() => listView1.Items.Add(item));
                    i++;
                }
        }
}










//Constructor
        public MyClass()
        {
        // myList is a list containing some items of type Tag
        // Tag is a class that implements NotifyPropertyChanged
        ChangedItems_ObsCollection&lt;Tag&gt;  testCollection = new ChangedItems_ObsCollection&lt;Tag&gt;( my_List&lt;Tag&gt; );
    }

    //property
        public ChangedItems_ObsCollection&lt;Tag&gt; TestCollection
        {
            get {   return testCollection ; }
        }

推荐答案

感谢您的回复!我修改了我的Form Class,如下所示,但现在我在列表视图中看到了更改的项目的两倍。

例如,如果10个项目发生变化,我会看到20个项目列表视图。

每个项目都是双倍且两者都具有相同的值。

Thank you for the reply! I modified my Form Class, as you can see below, but now i see in the list view exactly the double of the items that changed.
For example, if 10 items change, i see 20 items in the Listview.
Each item is double and both with the same value.
public partial class Form1 : Form
    {
        private MyClass myCollection = new MyClass();
    
//I defined Delegate here   
private delegate void DelegateListView(object sender,   System.Collections.Specialized.NotifyCollectionChangedEventArgs e);
 
        public Form1()
        {
            InitializeComponent();
            myCollection.TestCollection.CollectionChanged += MyCollection_CollectionChanged;           
        }
 
        private void MyCollection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if(this.InvokeRequired)
            {
                this.BeginInvoke(new DelegateListView(RecordStoricoCorrente_CollectionChanged), new object[] {sender,e});
                return;
            }

                this.UIThread(() => listView1.Items.Clear());
                int   i = 0;
 
                foreach (var tag in myCollection.TestCollection )
                {
                    ListViewItem item = new ListViewItem(i.ToString());
                    item.SubItems.Add(tag.Nome);
                    item.SubItems.Add(tag.Valore.ToString());
                    this.UIThread(() => listView1.Items.Add(item));
                    i++;
                }
        }
}


我假设UIThread方法使用类似于:
I assume UIThread method uses something like:
this.BeginInvoke(foo)



这可能与您正在使用的线程异步。

如果这个动作很快发生,可能是两个不同的线程同时调用了集合改变的事件。



尝试一些线程同步方法来确保那里只有一个线程处理列表视图。


This might be asynchronous to the thread you are working in.
If this action occurs rapidly, it could be that two different threads have invoked the collection changed event simultaneously.

Try some thread synchronization methods to make sure there is only one thread handling the list view.


这篇关于的ObservableCollection&LT; T&GT;在listView中显示重复(多个)值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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