List T vs BindingList T Advantages/DisAdvantages
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.
ObservableCollection(Of T) vs BindingList(Of T)?
Claber,
I would keep the BindingList, because BindingList supports more interfaces and more feature rich than ObservableCollection.
For example:
- BindingList implements IList of T, whereas ObservableCollection does not.
- BindingList implements ICancelAddNew interface that data binding mechanisms uses for cancelling the newly added item (when you clicked escape after adding a row to DataGridView, the row will dissappear).
I'm very new to WPF myself, and don't know the specific advantages ObservableCollection offers.
Hope this helps.
Advantages/Disadvantages of different implementations for Comparing Objects
Probably the biggest advantage to accepting a Comparison<T>
as opposed to an IComparer<T>
is the ability to write anonymous methods. If I have, let's say, a List<MyClass>
, where MyClass
contains an ID
property that should be used for sorting, I can write:
myList.Sort((c1, c2) => c1.ID.CompareTo(c2.ID));
Which is a lot more convenient than having to write an entire IComparer<MyClass>
implementation.
I'm not sure that accepting an IComparer<T>
really has any major advantages, except for compatibility with legacy code (including .NET Framework classes). The Comparer<T>.Default
property is only really useful for primitive types; everything else usually requires extra work to code against.
To avoid code duplication when I need to work with IComparer<T>
, one thing I usually do is create a generic comparer, like this:
public class AnonymousComparer<T> : IComparer<T>
{
private Comparison<T> comparison;
public AnonymousComparer(Comparison<T> comparison)
{
if (comparison == null)
throw new ArgumentNullException("comparison");
this.comparison = comparison;
}
public int Compare(T x, T y)
{
return comparison(x, y);
}
}
This allows writing code such as:
myList.BinarySearch(item,
new AnonymousComparer<MyClass>(x.ID.CompareTo(y.ID)));
It's not exactly pretty, but it saves some time.
Another useful class I have is this one:
public class PropertyComparer<T, TProp> : IComparer<T>
where TProp : IComparable
{
private Func<T, TProp> func;
public PropertyComparer(Func<T, TProp> func)
{
if (func == null)
throw new ArgumentNullException("func");
this.func = func;
}
public int Compare(T x, T y)
{
TProp px = func(x);
TProp py = func(y);
return px.CompareTo(py);
}
}
Which you can write code designed for IComparer<T>
as:
myList.BinarySearch(item, new PropertyComparer<MyClass, int>(c => c.ID));
Difference between ObservableCollection and BindingList
An ObservableCollection
can be updated from UI exactly like any collection. The true difference is rather straightforward:
ObservableCollection<T>
implements INotifyCollectionChanged
which provides notification when the collection is changed (you guessed ^^)
It allows the binding engine to update the UI when the ObservableCollection
is updated.
However, BindingList<T>
implements IBindingList
.
IBindingList
provides notification on collection changes, but not only that. It provides a whole bunch of functionality which can be used by the UI to provide a lot more things than only UI updates according to changes, like:
- Sorting
- Searching
- Add through factory (AddNew member function).
- Readonly list (CanEdit property)
All these functionalities are not available in ObservableCollection<T>
Another difference is that BindingList
relays item change notifications when its items implement INotifyPropertyChanged
. If an item raises a PropertyChanged
event, the BindingList
will receive it an raises a ListChangedEvent
with ListChangedType.ItemChanged
and OldIndex=NewIndex
(if an item was replaced, OldIndex=-1
). ObservableCollection
doesn't relay item notifications.
Note that in Silverlight, BindingList
is not available as an option: You can however use ObservableCollection
s and ICollectionView
(and IPagedCollectionView
if I remember well).
Difference between updating a listbox using Items.Add() and using a BindingSource in C#?
In the first example where you add an item to a ListBox
, the list is entirely "owned" by that UI control. If you wanted to perform other operations on that list like adding or removing items or doing something with that list of items, you'd have to get it from the ListBox
. Then, if you modified the list, you'd have to either make corresponding changes to the items in the ListBox
or just clear it and add the items back to it.
In the second example you're binding to a List<Car>
. That list "owns" its contents. If you wanted to do some operations with those cars, you could just pass that list to another method, and after it's modified you can reset the bindings to update the control. Or if the underlying data source changes you can load it into that List
and reset the bindings.
ListBox
is not strongly typed. You can add any object to it. A List<Car>
will contain only items of type Car
.
If all you want to do is display items on the screen so that users can see them and pick one then just adding directly to the ListBox
may be sufficient. But if that list reflects a data source that changes then keeping that source separate and binding it to the control is probably better.
difference between IList and IBindingList
They are designed for different scenarios
IList
is designed to be a very efficient container of objects. It's minimalisticIBindingList
is designed to be a container of objects which provides a richer API that enables more scenarios such as UI data binding.
If you dig into the APIs you'll find that IBindingList
has a much richer event collection than IList
(which has none). It takes the trade off of extra overhead to provide a richer API that fits more scenarios such as UI data binding.
Binding List to several ComboBoxes
Use a BindingList<T>
This class allows you to handle the interaction with your list separately for each of the combos
For example
List<string> names = new List<string>()
{"Steve", "Mark", "Luke", "John", "Robert"};
BindingList<string> bl1 = new BindingList<string>(names);
ComboBox_Rank_0.DataSource = bl1;
BindingList<string> bl2 = new BindingList<string>(names);
ComboBox_Rank_1.DataSource = bl2;
The BindingList<T>
requires using System.ComponentModel;
and notice that you don't require the new string[] syntax in the constructor of your list
Why doesn't ToList() work as expected?
You need to add the .ToList()
var t = latesProcessList
.Select(p=>p.ProcessName)
.Except(snapShotList.Select(q=>q.ProcessName))
.ToList();
Related Topics
Should C# Have Multiple Inheritance
How to Call a Non-Static Method from a Static Method in C#
Is Accessing a Variable in C# an Atomic Operation
How to Pass SQLparameter to In()
Combination of List<List<Int>>
How to Fix a .Net Windows Application Crashing at Startup with Exception Code: 0Xe0434352
Convert Comma Separated String of Ints to Int Array
Deserialize JSON Array Stream One Item at a Time
Trying to Use the C# Spellcheck Class
How to Create a Hashcode in .Net (C#) for a String That Is Safe to Store in a Database
Why Are Properties Without a Setter Not Serialized
How Does Inheritance Work for Attributes
ASP.NET Core: Exclude or Include Files on Publish
Avoiding First Chance Exception Messages When the Exception Is Safely Handled