C#inheritance类BindingList 不更新控件

我有一个inheritance自BindingList的类,用于将排序应用于绑定列表。 排序工作正常,但是当我从列表中添加或删除项目时,有界控件不会更新。 我想我在课堂上想念一些东西,但我不知道是什么。

我在网上找到了这个类的代码,但我不知道在哪里找到它。 我的问题是,当我更新或删除列表中的项目时,为什么这个类不会更新我的控件?

这是完整的课程

public class SortableBindingList : BindingList { #region Membar variables private bool _isSortedValue; private ArrayList _sortedList; private ArrayList _unsortedItems; private PropertyDescriptor _sortPropertyValue; private ListSortDirection _sortDirectionValue; #endregion #region Constructor public SortableBindingList() { } public SortableBindingList(IList list):base(list) { } #endregion #region Overrided Properties protected override bool SupportsSearchingCore { get { return true; } } protected override bool SupportsSortingCore { get { return true; } } protected override bool IsSortedCore { get { return _isSortedValue; } } protected override PropertyDescriptor SortPropertyCore { get { return _sortPropertyValue; } } protected override ListSortDirection SortDirectionCore { get { return _sortDirectionValue; } } #endregion #region Public methods public int Find(string property, object key) { // Check the properties for a property with the specified name. PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T)); PropertyDescriptor prop = properties.Find(property, true); // If there is not a match, return -1 otherwise pass search to // FindCore method. if (prop == null) return -1; else return FindCore(prop, key); } public void RemoveSort() { RemoveSortCore(); } public void Sort(string property, ListSortDirection direction) { // Get all the properties of the object T PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T)); // Find the specified property in de collection and ignore case PropertyDescriptor prop = properties.Find(property, true); if (prop != null) ApplySortCore(prop, direction); } #endregion #region Overrided methods // The FindCore method searches a list and returns the index of a found item protected override int FindCore(PropertyDescriptor prop, object key) { // Get the property info for the specified property. PropertyInfo propInfo = typeof(T).GetProperty(prop.Name); T item; if (key != null) { // Loop through the items to see if the key // value matches the property value. for (int i = 0; i < Count; ++i) { item = (T)Items[i]; if (propInfo.GetValue(item, null).Equals(key)) return i; } } return -1; } protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction) { _sortedList = new ArrayList(); // Check to see if the property type we are sorting by implements // the IComparable interface. Type interfaceType = prop.PropertyType.GetInterface("IComparable"); if (interfaceType != null) { // If so, set the SortPropertyValue and SortDirectionValue. _sortPropertyValue = prop; _sortDirectionValue = direction; _unsortedItems = new ArrayList(this.Count); // Loop through each item, adding it the the sortedItems ArrayList. foreach (Object item in this.Items) { _sortedList.Add(prop.GetValue(item)); _unsortedItems.Add(item); } // Call Sort on the ArrayList. _sortedList.Sort(); T temp; // Check the sort direction and then copy the sorted items // back into the list. if (direction == ListSortDirection.Descending) _sortedList.Reverse(); for (int i = 0; i < this.Count; i++) { int position = Find(prop.Name, _sortedList[i]); if (position != i) { temp = this[i]; this[i] = this[position]; this[position] = temp; } } _isSortedValue = true; // Raise the ListChanged event so bound controls refresh their // values. OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); } else // If the property type does not implement IComparable, let the user // know. throw new NotSupportedException("Cannot sort by " + prop.Name + ". This" + prop.PropertyType.ToString() + " does not implement IComparable"); } protected override void RemoveSortCore() { int position; object temp; // Ensure the list has been sorted. if (_unsortedItems != null) { // Loop through the unsorted items and reorder the // list per the unsorted list. for (int i = 0; i  0 && position != i) { temp = this[i]; this[i] = this[position]; this[position] = (T)temp; i++; } else if (position == i) i++; else // If an item in the unsorted list no longer exists, // delete it. _unsortedItems.RemoveAt(i); } _isSortedValue = false; OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); } } #endregion } 

无法重现; 这里好像很好:

 static class Program { [STAThread] static void Main() { Button btn; var data = new SortableBindingList { new Foo { Bar = "abc" } }; using (var form = new Form { Controls = { (btn = new Button { Dock = DockStyle.Bottom, Text = "add"}), new DataGridView { Dock = DockStyle.Fill, DataSource = data, AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells } } }) { btn.Click += delegate { data.Add(new Foo { Bar = DateTime.Now.Ticks.ToString()}); }; Application.Run(form); } } } class Foo { public string Bar { get; set; } } 

你能给出一个不可更新的可重复的例子吗?


评论:代码使用的东西与:

 data = new BindingList(someOtherData.Where(lambda).ToList()); 

现在, 如果我们添加someOtherData ,我们确实不会注意到任何差异。 Collection一个细微之处在于,如果将列表传递给构造函数,该列表将成为实际的后备列表,但是:

a:除非知道任何事件,否则不能提出任何事件; 它能够知道的唯一方法是它是否看到了加法 ,即加法通过BindingList.Add ,而不是后备列表的Add 。 这可能会导致奇怪的效果,重新加载或重新绑定数据可能会使项目神奇地出现(在某些情况下,不是这一项)。

b:在这种情况下,支持列表不是someOtherData ,而是由LINQ( ToList() )生成的单独列表,因此即使向someOtherData添加内容也不会导致绑定列表支持列表看到新项目。

简而言之:如果您希望传播数据更改,则需要将绑定列表视为“主”。 其他; 重新绑定数据。