首页 > 代码库 > 扩展BindingList,防止增加、删除项时自动更新界面而不出现“跨线程操作界面控件 corss thread operation”异常

扩展BindingList,防止增加、删除项时自动更新界面而不出现“跨线程操作界面控件 corss thread operation”异常

在做界面程序时,常常需要一些数据类,界面元素通过绑定等方式显示出数据,然而由于UI线程不是线程安全的,一般都需要通过Invoke等方式来调用界面控件。但对于数据绑定bindingList而言,没法响应listchang事件,导致后端的grid等控件不能更新数据。废了好大的劲终于找到一个UIBindingList,实现线程数据的同步!

using System;using System.ComponentModel;using System.Threading;using System.Windows.Forms;namespace TempForms{    public partial class Form1 : Form    {        public Form1()        {            InitializeComponent();            Initial();        }        private UiBindList<int> _list;        private void Initial()        {            _list = new UiBindList<int> { SynchronizationContext = SynchronizationContext.Current };            bindingSource1.DataSource = _list;            new Thread(() =>            {                while (true)                {                    Thread.Sleep(1000);                    var newItem = DateTime.Now.Second;                    _list.Add(newItem);                    Thread.Sleep(1000);                    _list.Remove(newItem);                }            })            {                IsBackground = true,            }            .Start();        }    }    /// <summary>    /// 扩展BindingList,防止增加、删除项时自动更新界面而不出现“跨线程操作界面控件”异常    /// </summary>    class UiBindList<T> : BindingList<T>    {        /// <summary>        /// 界面同步上下文        /// </summary>        public SynchronizationContext SynchronizationContext { get; set; }        /// <summary>        /// 使用此方法执行一切操作上下文相关的操作        /// </summary>        private void Excute(Action action, object state = null)        {            if (SynchronizationContext == null)                action();            else                SynchronizationContext.Post(d => action(), state);        }        public new void Add(T item)        {            Excute(() => base.Add(item));        }        public new void Remove(T item)        {            Excute(() => base.Remove(item));        }    }}