简体   繁体   中英

WPF ObservableCollection<T> vs BindingList<T>

In my WPF app I have a XamDataGrid. The grid is bound to an ObservableCollection. I need to allow users to insert new rows through the grid but it turns out that in order for the "Add New Row" row to be available, the xamDataGrid's source needs to implement IBindingList. ObservableCollection does not implement that interface.

If I change my source to a BindingList, it works ok. However, from what I can understand from reading up on this topic, BindingList is really a WinForms thing and is not fully supported in WPF.

Would I be making a mistake if I changed all of my ObservableCollections to BindingLists? Does anyone have any other suggestions as to how I can get add new row functionality for my xamDataGrid while keeping the source as an ObservableCollection? It is my understanding that there are a number of different grids that require IBindingList to be implemented in order to support add new row functionality but most solutions I see are to just switch to BindingList.

Thanks.

The IBindingList interface and BindingList class are defined in the System.ComponentModel namespace, and so are not strictly Windows Forms related.

Have you checked is xamGrid supports binding to a ICollectionView source? If so, you could expose your data sources using this interface and back it using a BindingListCollectionView .

You could also create a subclass of ObservableCollection<T> and implement the IBindingList interface:

using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Collections.ObjectModel;

public class ObservableBindingList<T> : ObservableCollection<T>, IBindingList
{
    //  Constructors
    public ObservableBindingList() : base()
    {
    }

    public ObservableBindingList(IEnumerable<T> collection) : base(collection)
    {
    }

    public ObservableBindingList(List<T> list) : base(list)
    {
    }

    //  IBindingList Implementation
    public void AddIndex(PropertyDescriptor property)
    {
        throw new NotImplementedException();
    }

    public object AddNew()
    {
        throw new NotImplementedException();
    }

    public bool AllowEdit
    {
        get { throw new NotImplementedException(); }
    }

    public bool AllowNew
    {
        get { throw new NotImplementedException(); }
    }

    public bool AllowRemove
    {
        get { throw new NotImplementedException(); }
    }

    public void ApplySort(PropertyDescriptor property, ListSortDirection direction)
    {
        throw new NotImplementedException();
    }

    public int Find(PropertyDescriptor property, object key)
    {
        throw new NotImplementedException();
    }

    public bool IsSorted
    {
        get { throw new NotImplementedException(); }
    }

    public event ListChangedEventHandler ListChanged;

    public void RemoveIndex(PropertyDescriptor property)
    {
        throw new NotImplementedException();
    }

    public void RemoveSort()
    {
        throw new NotImplementedException();
    }

    public ListSortDirection SortDirection
    {
        get { throw new NotImplementedException(); }
    }

    public PropertyDescriptor SortProperty
    {
        get { throw new NotImplementedException(); }
    }

    public bool SupportsChangeNotification
    {
        get { throw new NotImplementedException(); }
    }

    public bool SupportsSearching
    {
        get { throw new NotImplementedException(); }
    }

    public bool SupportsSorting
    {
        get { throw new NotImplementedException(); }
    }
}

Alternately, you could subclass BindingList<T> and implement the INotifyCollectionChanged interface.

I am not familiar with IBindingList, but I would probably take the approach of writing an adapter and/or extension class that adapts an ObservableCollection to an IBindingList. This way, you can keep your familiar ObservableCollection code (and also use it in other places besides the Infragistic DataGrid).

I think you're out of luck either way. IBindingList won't fully be supported by the grid, so you'll lose things like sorting I beleive. But OC doesn't do the AddNew behavior.

I wouldn't use IBindingList, I'd probably just add a button to insert a new item into the list and then set the grid to edit that item.

If you can upgrade to NetAdvantage 2011 Volume 2 the add new record will work when bound to an ObservableCollection.

If you are using NetAdvantage 2011 Volume 1 or older, then the XamDataGrid also supports the IEditableCollectionView interface when its CanAddNew property returns true. You could use a ListCollectionView giving it the instance of your ObservableCollection and then bind the XamDataGrid to the ListCollectionView.

You could also use the previous suggestion of deriving from ObservableCollection and implementing IBindingList on your derived class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM