BindingList<T>, где T - интерфейс, который реализует другой интерфейс

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

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 ответ

Решение

Свойства получаются через (косвенно) 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, но оба они сложны. Если честно, привязка данных просто легче работает с классами, чем с интерфейсами.

Другие вопросы по тегам