2010-08-19 61 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