Bindinglist c что это

от admin

Binding to BindingList

BindingList is a generic list type, that provides additional control over list items, i.e. the items in RadChartView can be easily edited, removed or added. BindingList also surfaces events that notify when the list has been changed. The example below creates a list of MyCustomObject, initializes the list and assigns it to the BarSeries object in RadChartView.

Figure 1: Binding to BindingList

In order to allow RadChartView to automatically reflect changes in the data source, your object should implement the INotifyPropertyChanged interface:

Binding to BindingList

Once the interface is implemented and your collection implement IBindingList, just like the BindingList does, changes are automatically reflected. Here is a sample of adding a new record:

List<T> vs BindingList<T> Advantages/DisAdvantages

Can someone describe what the difference between the two are for my project.

Currently I have a List<MyClass> and set the BindingSource to that and a DataGridView to the BindingSource.

I have implemented IEditableObject so when CancelEdit is called I revert my object back to what it was with a Memberwise.Clone()

Will changing my List to a BindingList solve any of this and what are the advantages of using a BindingList?

2 Answers 2

A List<> is simply an automatically resizing array, of items of a given type, with a couple of helper functions (eg: sort). It’s just the data, and you’re likely to use it to run operations on a set of objects in your model.

A BindingList<> is a wrapper around a typed list or a collection, which implements the IBindingList interface. This is one of the standard interfaces that support two-way databinding. It works by implementing the ListChanged event, which is raised when you add, remove, or set items. Bound controls listen to this event in order to know when to refresh their display.

When you set a BindingSource’s DataSource to a List<> , it internally creates a BindingList<> to wrap your list. You may want to pre-wrap your list with a BindingList<> yourself if you want to access it outside of the BindingSource, but otherwise it’s just the same. You can also inherit from BindingList<> to implement special behavior when changing items.

IEditableObject is handled by the BindingSource. It’ll call BeginEdit on any implementing object when you change the data in any bound control. You can then call EndEdit/CancelEdit on the BindingSource and it will pass it along to your object. Moving to a different row will call EndEdit as well.

BindingList vs ObservableCollection

There are a lot of people asking around what is the difference between BindingList<T> and ObservableCollection<T> and therefore, there are a lot of answers. I am writing this entry so that next time I look it up, I save StackOverflow some bandwidth. Also, because my blog is cooler 🙂

So, the first difference between BindingList and ObservableCollection is that BindingList implements cascading notifications of change. If any of the items in the list implements INotifyPropertyChanged, it will accept any change from those items and expose it as a list changed event, including the index of the item that initiated the change. ObservableCollection does not do that. So BindingList is better, right?

Wrong. BindingList is not «properly supported» by WPF , say some. Why is that? Well, because BindingList, as its MSDN page says, is just «an alternative to implementing the complete IBindingList interface». Yes, you’ve got it. BindingList is a lazy, thin, ineffective implementation of the interface. The Missing Docs blog has a very good explanation of this. Do keep in mind that BindingList was created during the time of Windows Forms and is being used by WPF only as an afterthought.

So let’s use ObservableCollection then! No. The functionalities implemented by BindingList are far superior to that of ObservableCollection. Just thinking that you must somehow handle changes of every object in the list is killing the idea.

A subtle recommendation on the same MSDN page goes like this: «the typical solutions programmer will use a class that provides data binding functionality, such as BindingSource, instead of directly using BindingList». Well, what does that mean? It means using System.Windows.Forms.BindingSource, which does about everything, since it implements IBindingListView, IBindingList, IList, ICollection, IEnumerable, ITypedList, ICancelAddNew, ISupportInitializeNotification, ISupportInitialize, ICurrencyManagerProvider and is also a subclass of Component. A bit heavy, though, isn’t it?

An interesting idea comes from a StackOverflow user: implement IBindingList on a subclass of ObservableCollection<T>. Should be enough to implement a scalable version of IBindingList.

There is more. The BindingListCollectionView page says «Specifically, IBindingList is required for BindingListCollectionView, and IBindingListView is an optional interface that gives additional sorting and filtering support.», which indicates that IBindingListView is also useful when getting a collection view for your object.

To recap: the best solution seems to be an ObservableCollection<T> that also implements IBindingListView (which itself implements IBindingList). The implementation must be scalable (getting the index of an object that causes a change in an efficient manner), though and I wonder, if I am implementing IBindingList, why should I even bother with inheriting from ObservableCollection? The same StackOverflow user seems interested only in the INotifyCollectionChanged interface for the ObservableCollection which is also implemented by IBindingListView!

Читать:
Определить что взять за уравнение или x

Therefore, let’s implement a class that explicitly implements IBindingListView and IList<T>, then publish the members we actually use! What could possibly go wrong? My idea is to store the index of an item next to the item, therefore removing the need to search for it. It seems that I must first implement an advanced List<T>, with a fast and efficient IndexOf method, then I can basically just copy paste the BindingList code and use this class of mine as the base. Unfortunately, BindingList uses Collection<T> as the base class, which itself implements IList<T>, IList, IReadOnlyList<T>. It seems I will have to implement all.

For an implementation of IBindingView, check this out: BindingListView

I’ve decided to implement the IndexOf caching as a dictionary with the objects as keys. The values are lists of integers representing all indexes of that value or object. Frankly I never realized that IndexOf for lists was not taking a start parameter, so it only returns the first occurrence of an item in the list.

There are three classes: AdvancedCollection is a fast IndexOf implementation of Collection. AdvancedBindingList is the copy pasted code of BindingList, with the base class changed from Collection to AdvancedCollection and with INotifyCollectionChanged implemented over it. SecurityUtils is only needed for the AddNew method of IBindingList and is again copy pasted from the Microsoft code. Enjoy!

Binding Controls to Data Created at Runtime

DevExpress data-aware .NET WinForms controls can be bound to databases, XML files and lists of data created at runtime. This topic shows you how to bind controls to lists of data.

Concepts

Suppose you have an object that represents a data record and a list of these records should be displayed in a data-aware control. To allow this list to be bound to a control, you can do one of the following:

  • Use the System.ComponentModel.BindingList<> or System.Collections.Generic.List<> generic types to create a list. Unlike the List<> class, the BindingList<> class supports change notifications. When bound to this data source, a data-aware control will update itself when the underlying data changes.
  • Create a class encapsulating a list of records and implement the IList, IListSource, ITypedList or IBindingList interface for this class. The differences between these interfaces is described in the following section.
  • Create an IEnumerable<T> collection that stores your records. Note that the IEnumerable interface allows users to view collection records, not modify them or add\remove collection items.

The simplest way to create a list is to use the BindingList<> generic type.

Consider a sample MyRecord class encapsulating a data record:

A list of MyRecord objects can be created and bound to a data-aware control as follows:

To populate the list with data, you can use the following code:

When bound to a BindingList<> object, the data-aware control automatically subscribes to the BindingList<>.ListChanged event. This allows it to receive notifications and update itself when the underlying data changes.

Instead of creating custom lists, you can use a DataTable object and fill it with data at runtime, if this better suits your requirements.

IList vs ITypedList vs IBindingList

As stated above, the control’s data source can implement one of three interfaces. The following describes the difference between the data sources that implement each interface type.

  • Objects implementing the IList interface — Such data sources must have at least one “record”. Otherwise, bound controls will not be able to create any rows. Controls bound to such data sources will not be notified of any data changes and thus must be updated manually.
  • Objects implementing the ITypedList interface — In this case, it is not necessary to have any “records” for rows to be created. Data change notifications are not supported.
  • Objects implementing the IBindingList interface (derived from the IList) — This data source type does not have the shortcomings of the other interfaces. The interface declares the ListChanged event, which is used by the control to update itself when bound data is changed.

Example

This example binds a GridControl to a collection of custom Record objects and demonstrates the following features:

Assigning an inplace editor (combo box) to a column

Specifying a column’s display name and data format by applying DataAnnotation attributes to Record class properties

Похожие статьи