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 控件?
我认为这是因为 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(当你这样做时编译器会给你一个警告)