Interface implements a different interface, causing issues binding to Combobox

允我心安 提交于 2019-12-12 03:53:24

问题


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 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?


回答1:


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)



来源:https://stackoverflow.com/questions/3524676/interface-implements-a-different-interface-causing-issues-binding-to-combobox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!