I am learning Fluent NHibernate and this issue arose from that project.
I have a base Class and a base Interface:
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();
}
which I inherit all of my other Domain classes from:
public class Item:Base, IItem
{
public virtual string Name { get; set; }
public override bool IsValid()
{
<snip>
}
<snip>
}
public开发者_JAVA百科 interface IItem: IBase
{
string Name { get; set; }
<snip>
}
However when I try and bind a list of all Items to a winforms Combobox I get an error.
var ds = from i in GetSession().Linq<IItem>() select i;
cmbItems.DataSource = ds.ToArray();
this.cmbItems.DisplayMember = "Name";
this.cmbItems.ValueMember = "Id";
I get an error:
Cannot bind to the new value member. Parameter name: value
I have figured out that this occurs because I am implementing IBase on IItem. If I modify IItem it works fine.
public interface IItem: IBase
{
Guid Id { get; set; }
string Name { get; set; }
<snip>
bool IsValid();
}
So beyond the practical, just make it work, am I doing interfaces correctly? Should I not have interfaces implement other interfaces? If I should have IItem implement IBase, is there a way to bind properly to a Winforms control?
I think that's because WinForms binding system is based on the use of TypeDescriptor
, and TypeDescriptor.GetProperties(typeof(IItem))
returns only the declared properties... So the ComboBox
finds Name
because it's declared in IItem
, but not Id
.
To work around this problem, you could create an anonymous type with the properties you need:
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";
Anyway, I don't think you should redeclare Id
and IsValid
in IItem
, because it would hide the properties declared in IBase
(the compiler gives you a warning when you do that)
精彩评论