2010-08-19 42 views
0

我正在学习流利的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控件?

回答

4

我认为这是因为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重新声明IdIsValid,因为它会隐藏属性声明在IBase(编译器给你一个警告,当你这样做)

+0

我试着做一个匿名类型,但我得到一个错误“对象必须实现IConvertible”,在ds.ToArray();有任何想法吗? – 2010-08-19 18:36:04

+1

它适用于我,使用集合而不是NHibernate查询...我认为这是因为'Linq '返回'IQueryable ',所以它试图在SQL中执行投影。尝试用'Linq ()替换'Linq ()'.AsEnumerable()' – 2010-08-19 18:46:52

+0

谢谢托马斯,像一个魅力 – 2010-08-19 19:48:51