BindingList <T>, где T - интерфейс, который реализует другой интерфейс - PullRequest
4 голосов
/ 04 декабря 2011

Я застрял в BindingList, где T - это интерфейс, расширяющий интерфейс. Когда я использую этот bindingList в привязках, только свойства из T видны, а свойства из унаследованного интерфейса A - нет. Почему это происходит? Это похоже на ошибку .net. Это мне нужно для моих 2 проектов, чтобы поделиться некоторыми общими функциями. Кроме того, список привязки имеет пустой PropertyDescriptor, когда событие PropertyChanged туннелируется из baseImplementation. Прикрепленные интерфейсы и реализации. Метод настройки в конце

interface IExtendedInterface : IBaseInterface
{
    string C { get; }
}

interface IBaseInterface : INotifyPropertyChanged
{
    string A { get; }
    string B { get; }
}

public class BaseImplementation : IBaseInterface
{
    public string A
    {
        get { return "Base a"; }
    }

    public string B
    {
        get { return "base b"; }
        protected set
        {
            B = value;
            OnPropertyChanged("B");
        }
    }

    protected void OnPropertyChanged(string p)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(p));
    }

    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
}

public class ExtendedImplementation : BaseImplementation, IExtendedInterface
{
    public string C
    {
        get { return "Extended C"; }
    }
}

 private void SetupData()
    {
        BindingList<IExtendedInterface> list = new BindingList<IExtendedInterface>();
        list.Add(new ExtendedImplementation());
        list.Add(new ExtendedImplementation());
        dataGridView1.DataSource = list;
    }

1 Ответ

6 голосов
/ 04 декабря 2011

Свойства получены через (косвенно) TypeDescriptor.GetProperties (typeof (T)), но поведение такое, как и ожидалось.Свойства от интерфейсов никогда не возвращаются, даже из моделей на основе классов, если только они не находятся в открытом API этого типа (что для интерфейсов означает для непосредственного типа ).Наследование классов отличается, потому что эти члены все еще находятся в общедоступном API.Когда интерфейс: ISomeOtherInterface, то есть «реализует», а не «наследует».Чтобы привести простой пример того, когда это может быть проблемой, рассмотрим (полностью легально):

interface IA { int Foo {get;} }
interface IB { string Foo {get;} }
interface IC : IA, IB {}

Сейчас;что такое IC.Foo?

Вы могли бы обойти это, зарегистрировав собственный интерфейс TypeDescriptionProvider или используя ITypedList, но оба они сложны.Честно говоря, привязка данных легче работает с классами, чем с интерфейсами.

...