接口实现了不同的接口,导致绑定到 Combobox 的问题

Nat*_*oop 0 c# data-binding design-patterns interface winforms

我正在学习 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();
}
Run Code Online (Sandbox Code Playgroud)

我从以下继承了所有其他域类:

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>
}
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试将所有项目的列表绑定到 winforms Combobox 时,出现错误。

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

        this.cmbItems.DisplayMember = "Name";
        this.cmbItems.ValueMember = "Id";
Run Code Online (Sandbox Code Playgroud)

我收到一个错误:

无法绑定到新值成员。参数名称:值

我发现这是因为我在 IItem 上实现了 IBase。如果我修改 IItem 它工作正常。

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

所以超越实际,让它工作,我是否正确地做接口?我不应该让接口实现其他接口吗?如果我应该让 IItem 实现 IBase,有没有办法正确绑定到 Winforms 控件?

Tho*_*que 5

我认为这是因为 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";
Run Code Online (Sandbox Code Playgroud)

无论如何,我认为你不应该重新声明Idand IsValidin IItem,因为它会隐藏声明的属性IBase(当你这样做时编译器会给你一个警告)