开发者

Interface implements a different interface, causing issues binding to Combobox

开发者 https://www.devze.com 2023-01-12 20:11 出处:网络
I am learning Fluent NHibernate and this issue arose from that project. I have a base Class and a base Interface:

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)

0

精彩评论

暂无评论...
验证码 换一张
取 消