接口实现了不同的接口,导致问题绑定到Combobox
问题描述:
我正在学习流利的NHibernate,这个问题产生于该项目。接口实现了不同的接口,导致问题绑定到Combobox
我有一个基类和基接口:
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 Combobox我得到一个错误。
var ds = from i in GetSession().Linq<IItem>() select i;
cmbItems.DataSource = ds.ToArray();
this.cmbItems.DisplayMember = "Name";
this.cmbItems.ValueMember = "Id";
我得到一个错误:
Cannot bind to the new value member. Parameter name: value
我已经想通了,这是因为我对的iItem实施IBASE。如果我修改IItem它工作正常。
public interface IItem: IBase
{
Guid Id { get; set; }
string Name { get; set; }
<snip>
bool IsValid();
}
所以超出了实际,只是让它工作,我的接口是否正确?我应该没有接口实现其他接口?如果我应该有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";
无论如何,我不认为你应该在IItem
重新声明Id
和IsValid
,因为它会隐藏属性声明在IBase
(编译器给你一个警告,当你这样做)
我试着做一个匿名类型,但我得到一个错误“对象必须实现IConvertible”,在ds.ToArray();有任何想法吗? – 2010-08-19 18:36:04
它适用于我,使用集合而不是NHibernate查询...我认为这是因为'Linq'返回'IQueryable ',所以它试图在SQL中执行投影。尝试用'Linq ()替换'Linq ()'.AsEnumerable()' –
2010-08-19 18:46:52
谢谢托马斯,像一个魅力 – 2010-08-19 19:48:51