Интерфейс реализует другой интерфейс, вызывая проблемы привязки к Combobox - PullRequest
0 голосов
/ 19 августа 2010

Я изучаю Fluent NHibernate, и эта проблема возникла из этого проекта.

У меня есть базовый класс и базовый интерфейс:

public abstract class Base : IBase
{
    public virtual Guid Id { get; set; }
    public virtual bool IsValid()
    {
        return false;
    }
}

public interface IBase
{
    Guid Id { get; set; }
    bool IsValid();
}

, от которого я наследую все остальные классы своего домена:

public class Item:Base, IItem
{
    public virtual string Name { get; set; }

    public override bool IsValid()
    {
        <snip>
    }
    <snip>
}

public interface IItem: IBase
{
    string Name { get; set; }
    <snip>
}

Однако, когда я пытаюсь привязать список всех предметов к комбинированному списку winforms, я получаю ошибку.

        var ds = from i in GetSession().Linq<IItem>() select i;
        cmbItems.DataSource = ds.ToArray();

        this.cmbItems.DisplayMember = "Name";
        this.cmbItems.ValueMember = "Id";

Я получаю сообщение об ошибке:

Невозможно выполнить привязку к новому элементу значения. Имя параметра: значение

Я понял, что это происходит потому, что я внедряю IBase на IItem. Если я изменю IItem, он будет работать нормально.

public interface IItem: IBase
{
    Guid Id { get; set; }
    string Name { get; set; }
    <snip>
    bool IsValid();
}

Итак, помимо практического, просто заставьте его работать, я правильно делаю интерфейсы? Разве я не должен иметь интерфейсы для реализации других интерфейсов? Если мне нужно, чтобы IItem внедрил IBase, есть ли способ правильно привязать элемент управления Winforms?

1 Ответ

4 голосов
/ 19 августа 2010

Я думаю, это потому, что система привязки WinForms основана на использовании TypeDescriptor, а TypeDescriptor.GetProperties(typeof(IItem)) возвращает только объявленные свойства ... Так что ComboBox находит Name, потому что оно объявлено в IItem, ноне Id.

Чтобы обойти эту проблему, вы можете создать анонимный тип с нужными вам свойствами:

    var ds = from i in GetSession().Linq<IItem>() select new { i.Id, i.Name };
    cmbItems.DataSource = ds.ToArray();

    this.cmbItems.DisplayMember = "Name";
    this.cmbItems.ValueMember = "Id";

В любом случае, я не думаю, что вы должны переопределять Id и IsValid в IItem, потому что это скрыло бы свойства, объявленные в IBase (компилятор выдает предупреждение при этом)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...