请问C#中如何实现在List<T>中成员的值发生变化的时候,触发一个事件?c#List<T>

解决方案 »

  1.   

    自己写呗,继承list,set的时候触发事件,事件再用delegate丢出去。
      

  2.   

    WPF中是用INotifyPropertyChanged接口
      

  3.   

    你可以用BindingList<T>,前提是这个T必须实现INotifyPropertyChanged接口。
      

  4.   

    我的做法是,新建一个类继承自List<T>,list的变化无非就是add,insert,remove,clear等,所以覆盖这些事件,并触发某个事件new void Add()
    {
    base.Add();
    DoEvents();//触发自定义事件
    }
      

  5.   

    ObservableCollection
    http://www.cnblogs.com/mgen/archive/2012/09/29/2707912.html
      

  6.   

    可能是我的思路有问题,项目是WPF开发的,
    我将一组textbox绑定到了这个List<T>上,当textbox的值发生变化时,这个List<T>的值也实时发生了变化,现在的问题就是我想当textbox变化时,触发一些事件,从textbox入手太麻烦了,本来想给所有textbox绑定事件,但用的控件无法遍历出来所有的textbox,一个一个的为textbox添加事件也不现实,只有退后一步,从List<T>着手了。所以List<T>的变化是内部成员的值发生了变化,这个该怎么搞?
      

  7.   

    WPF,则用5楼dongxinxi朋友建议的ObservableCollection<T>。
      

  8.   


    用ObservableCollection<T>也是同样的问题,
    在注册的时候可以监听PropertyChanged,但是如何监听这个集合对象内部成员值的变化?
    当内部成员值变化时,他会实时通知界面(我用List<T>也实现了),但我用什么方法可以截取到值变化了?以便我触发其他事件?
    设置UpdateSourceTrigger为PropertyChanged,也不会响应啊,
    PropertyChangedCallback和CoerceValueCallback都没有相应
      

  9.   


    T必须实现INotifyPropertyChanged接口
      

  10.   


    用ObservableCollection<T>也是同样的问题,
    在注册的时候可以监听PropertyChanged,但是如何监听这个集合对象内部成员值的变化?
    当内部成员值变化时,他会实时通知界面(我用List<T>也实现了),但我用什么方法可以截取到值变化了?以便我触发其他事件?
    设置UpdateSourceTrigger为PropertyChanged,也不会响应啊,
    PropertyChangedCallback和CoerceValueCallback都没有相应可以自定义一个事件,比如event EventHandler ItemTextChanged
    给那些要监视的
    textBox.TextChanged += (obj, evt) =>
    {    
        if(this.ItemTextChanged != null) this.ItemTextChanged(textBox, EventArgs.Empty);
    }
    当它们任何一个Text变化了都会触发ItemTextChanged,若需要其他参数自己重新定义事件参数类
      

  11.   


    T必须实现INotifyPropertyChanged接口
    INotifyPropertyChanged是为了实现当List<T>或ObservableCollection<T>中的值变化时,能实时在UI显示,我的问题就是,当他通知UI说值已经变化的时候,同时通知一下我(或我用什么方法截取到),好让我触发其他的事件?
      

  12.   


    T必须实现INotifyPropertyChanged接口
    INotifyPropertyChanged是为了实现当List<T>或ObservableCollection<T>中的值变化时,能实时在UI显示,我的问题就是,当他通知UI说值已经变化的时候,同时通知一下我(或我用什么方法截取到),好让我触发其他的事件?INotifyPropertyChanged
    接口里面有事件的啊 你怎么实现的接口。。
    仔细看下接口的定义代码吧 呵呵
      

  13.   

    你写一个控件类 把 text 付给 你写的这个类,我之前 也写过相同的东西private Control[] goods_HsCode = new Control[2];
            /// <summary>
            /// HS编码
            /// </summary>
            public Control[] Goods_HsCode
            {
                get { return goods_HsCode; }
                set { goods_HsCode = value; }
            }
    //在你的窗体加载事件中 给控件类的属性赋值
    customsInspectionControl.Goods_HsCode[0] = lblGoods_HsCode;
                customsInspectionControl.Goods_HsCode[1] = txtGoods_HsCode;//HS编码
    /// <summary>
            /// 此方法用于在弹出商品种类的时候调用中调用,
            /// 防止用户改变窗体上文本框的值时我不能及时获取,只有调用此方法才获取修改后的值
            /// 因为商品的值是通过list集合穿来的,而修改只是修改控件属性的值,调用此方法把控件的值赋给list集合对应的值
            /// </summary>
            /// <param name="customsInspectionControl"></param>
            public static void GoodsUpdateValue(CustomsInspectionControl customsInspectionControl) 
            {
                if (customsInspectionControl.ListQuery_GoodsInfoInspectionFJ.Count > 0)
                {
                    customsInspectionControl.ListQuery_GoodsInfoInspectionFJ[customsInspectionControl.GoodsPage].MillWorkPlant = customsInspectionControl.MillworkPlant[1].Text;
                    customsInspectionControl.ListQuery_GoodsInfoInspectionFJ[customsInspectionControl.GoodsPage].Goods_HsCode = customsInspectionControl.Goods_HsCode[1].Text;
                }
            }
    一个存储 你的lable 另一个存储 text
      

  14.   

    把textbox的 textchanged 事件注册到同一个处理程序
      

  15.   

    给你写个demo:using System;
    using System.Collections.ObjectModel;
    using System.ComponentModel;namespace ConsoleApplication1
    {
        class Program
        {
            private static ObservableCollection<DataType> List = new ObservableCollection<DataType>();        static void Main(string[] args)
            {
                List.CollectionChanged += List_CollectionChanged;
                List.Add(new DataType { Fa = "aaa", Fb = 1 });
                List.Add(new DataType { Fa = "bbb", Fb = 2 });
                List.Add(new DataType { Fa = "ccc", Fb = 3 });
                List.Add(new DataType { Fa = "ddd", Fb = 4 });
                List[3].Fb += 100;  //这个对象修改时,可以在方法obj_PropertyChanged中捕获。
                Console.ReadKey();
            }        static void List_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
            {
                if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
                {
                    var obj = (DataType)e.NewItems[0];
                    obj.PropertyChanged += obj_PropertyChanged;
                }
            }        static void obj_PropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                var obj = (DataType)sender;
                Console.WriteLine("Fa={0}, Fb={1}", obj.Fa, obj.Fb);
            }    }
        public class DataType : INotifyPropertyChanged
        {
            private string _Fa;        public string Fa
            {
                get { return _Fa; }
                set
                {
                    if (_Fa != value)
                    {
                        _Fa = value;
                        RaisePropertyChangedEvent("Fa");
                    }
                }
            }        private int _Fb;        public int Fb
            {
                get { return _Fb; }
                set
                {
                    if (_Fb != value)
                    {
                        _Fb = value;
                        RaisePropertyChangedEvent("Fb");
                    }
                }
            }        public event PropertyChangedEventHandler PropertyChanged;        private void RaisePropertyChangedEvent(string name)
            {
                if (this.PropertyChanged != null)
                    this.PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }
    }
      

  16.   

    两个层次,首先你要监听 ObservableCollection<T> 集合的“增加元素”事件。然后,监听这个T对象的属性修改事件。
      

  17.   

    嗯,第一层捕获时,写的完备一点(写为foreach)更好:static void List_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
        {
            foreach (DataType obj in e.NewItems)
                obj.PropertyChanged += obj_PropertyChanged;
        }
    }
      

  18.   

    原来监听List<T>中成员值的变化是这么弄的。
      

  19.   

    对于问题本身,SP大神的DEMO已经完美解决。。
    本人照版主的意思实现了下,(虽然并不是这个问题的答案),多写写总是好的 using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;namespace ExtendList
    {
        public delegate void ListChangedEventHandler<T>(object sender);    public class MyList<T> : List<T>
        {
            private int _count;        public String Action { get; set; }        private int MCount
            {
                get { return _count; }
                set
                {
                    if (_count != value)
                    {
                        _count = this.Count;
                        DoListChangedEvent();
                    }
                }
            }        public event ListChangedEventHandler<T> ListChanged;        private void DoListChangedEvent()
            {
                if (this.ListChanged != null)
                    this.ListChanged(this);
            }        public new void Add(T t)
            {
                base.Add(t);
                this.Action = "Add";
                MCount++;
            }        public new void Remove(T t)
            {
                base.Remove(t);
                this.Action = "Remove";
                MCount--;
            }
        }    class Program
        {
            static void Main(string[] args)
            {
                MyList<int> mylist = new MyList<int>();            mylist.ListChanged += List_CollectionChanged<int>;
                mylist.ListChanged += List_SummaryChanged<int>;            mylist.Add(1);
                mylist.Add(2);            mylist.Remove(1);            Console.ReadKey();
            }        static void List_CollectionChanged<T>(object sender)
            {
                Console.Write("{0} an item. Current items: {1} \n", ((MyList<T>)sender).Action, String.Join(" ", (MyList<T>)sender));
            }        static void List_SummaryChanged<T>(object sender)
            {
                Console.Write("*** {0} an item. Current summary: {1} \n", ((MyList<T>)sender).Action, ((MyList<T>)sender).Sum(item => int.Parse(item.ToString())));
            }
        }
    }
      

  20.   

    大家都用wpf的话,这种问题自然就熟悉了
      

  21.   

    对于问题本身,SP大神的DEMO已经完美解决。。
    本人照版主的意思实现了下,(虽然并不是这个问题的答案),多写写总是好的 using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;namespace ExtendList
    {
        public delegate void ListChangedEventHandler<T>(object sender);    public class MyList<T> : List<T>
        {
            private int _count;        public String Action { get; set; }        private int MCount
            {
                get { return _count; }
                set
                {
                    if (_count != value)
                    {
                        _count = this.Count;
                        DoListChangedEvent();
                    }
                }
            }        public event ListChangedEventHandler<T> ListChanged;        private void DoListChangedEvent()
            {
                if (this.ListChanged != null)
                    this.ListChanged(this);
            }        public new void Add(T t)
            {
                base.Add(t);
                this.Action = "Add";
                MCount++;
            }        public new void Remove(T t)
            {
                base.Remove(t);
                this.Action = "Remove";
                MCount--;
            }
        }    class Program
        {
            static void Main(string[] args)
            {
                MyList<int> mylist = new MyList<int>();            mylist.ListChanged += List_CollectionChanged<int>;
                mylist.ListChanged += List_SummaryChanged<int>;            mylist.Add(1);
                mylist.Add(2);            mylist.Remove(1);            Console.ReadKey();
            }        static void List_CollectionChanged<T>(object sender)
            {
                Console.Write("{0} an item. Current items: {1} \n", ((MyList<T>)sender).Action, String.Join(" ", (MyList<T>)sender));
            }        static void List_SummaryChanged<T>(object sender)
            {
                Console.Write("*** {0} an item. Current summary: {1} \n", ((MyList<T>)sender).Action, ((MyList<T>)sender).Sum(item => int.Parse(item.ToString())));
            }
        }
    }
    感谢您的耐心回答,我也学习到了很多管理List<T>的知识
    问题已经搞定了,通过对比,我发现监控List<T>的代价相对有点高,还是直接在TextBox层解决了,通过其他方法遍历出了所有的TextBox,为所有的TextBox绑定了事件,问题圆满解决。
    再次感谢!
      

  22.   

    非常感谢您的热心帮助!有您这样的大神真是程序员界的幸事啊!
    问题已经搞定了,通过对比,我发现监控List<T>的代价相对有点高,还是直接在TextBox层解决了,通过其他方法遍历出了所有的TextBox,为所有的TextBox绑定了事件,问题圆满解决。
    再次感谢!