C# 使用层类进行数据绑定

C# 使用层类进行数据绑定,c#,C#,当我有一个中间层类来保存我的对象列表时,我使用的ListBox无法正确填充DisplayMembers。没有图层类,一切都很好,但我的项目需要它。这里有一个非常简单的例子 乘客 class Passenger { private string name; public Passenger(string custName) { name = custName; } public string

当我有一个中间层类来保存我的对象列表时,我使用的ListBox无法正确填充DisplayMembers。没有图层类,一切都很好,但我的项目需要它。这里有一个非常简单的例子

乘客

class Passenger
{
        private string name;

        public Passenger(string custName)
        {
            name = custName;
        }

        public string Name
        {
            get { return name; }
        }
}
飞机

假设我用三个乘客的名字填充飞机,然后在下面编码

BindingSource bs = new BindingSource();
bs.DataSource = plane.passengerList;

aListBox.DataSource = bs;
aListBox.DisplayMember = "Name";
aListBox将显示多行文本“DataBinding.TestApp,LayerClass”,而不是乘客姓名。 如果我插入此代码,
bs.DataMember=“P”
aListBox.DisplayMember=“P.Name”,它将仅在列表框中显示第一名乘客的姓名,并忽略所有其他姓名

如何在列表框中显示所有乘客姓名?不重写Passenger类的ToString()方法。可能是我缺少的一些简单的东西,但我对数据绑定是新手。这是一个Windows窗体应用程序,对允许使用的内容有严格限制。不允许使用XAML或WPF。

尝试使用属性

     public List<LayerClass> passengerList { get; set; }
公共列表密码列表{get;set;}

而不仅仅是公共领域

看起来像两件事。如前所述,尝试使用属性而不是列表的字段:

public List<LayerClass> PassengerList { get; private set; }
或者,您可以在LayerClass中重写ToString函数:

class LayerClass
{
  private Passenger p;
  private int ID;

  public Passenger P
  {
    get { return p; }
    set { p = value; }
  }

  public override string ToString() {
    if (p == null) {
      return "No Passenger";
    } else {
      return p.Name;
    }
  }

}

这是你们的乘客舱结构

class Passenger
{
    private Int32 id;
    private string name;

    public Passenger(Int32 _id, string custName)
    {
        id = _id;
        name = custName;            
    }

    public Int32 ID
    {
        get { return id; }
    }

    public string Name
    {
        get { return name; }
    }
}
class Plane
{
    List<Passenger> lPassengers = null;
    public Plane()
    {

    }

    public List<Passenger> Passengers
    {
        get
        {
            if (this.lPassengers == null)
                this.lPassengers = new List<Passenger>();

            return this.lPassengers;
        }
        set { this.lPassengers = value; }
    }
}
这是你的飞机等级结构

class Passenger
{
    private Int32 id;
    private string name;

    public Passenger(Int32 _id, string custName)
    {
        id = _id;
        name = custName;            
    }

    public Int32 ID
    {
        get { return id; }
    }

    public string Name
    {
        get { return name; }
    }
}
class Plane
{
    List<Passenger> lPassengers = null;
    public Plane()
    {

    }

    public List<Passenger> Passengers
    {
        get
        {
            if (this.lPassengers == null)
                this.lPassengers = new List<Passenger>();

            return this.lPassengers;
        }
        set { this.lPassengers = value; }
    }
}
列表框数据绑定

this.aListBox.DataSource = objPlane.Passengers; 
this.aListBox.DataValueField = "ID";
this.aListBox.DataTextField = "Name";
this.aListBox.DataBind();

@Alex…尝试将名称作为属性添加到返回p.Name的LayerClass中。另外,列表框中的行数是否与列表框中的行数相同passengerList@MikeTWebb行数相同是的,它与本例中的乘客数匹配。在我的实际项目中(比这个示例大得多),我将xml反序列化为对象,并且存在多个属性。我还必须遵循设计模式规则,因此中间人有一个特定的目的,除了它现在所做的之外,我很可能无法修改它。谢谢。将其转换为属性会导致与公共成员相同的结果。不幸的是,将列表直接绑定到listBox会产生相同的结果。属性也没什么区别。@Alex这在我的机器上起作用了。请确保使用“P.Name”作为DisplayMember属性。您能够显示列表中的所有名称还是仅显示一个名称?如果您指的是重写ToString(),这不是我在问题中提到的我想做的事情,我在实际项目中有许多属性可供选择,Windows UI代码不是唯一使用这个中间类的项目,我不应该仅仅为了让它与UI项目一起工作而更改它的行为。是的,我回答的第一部分是有效的,它显示了我名单上的所有10名乘客。ToString覆盖只是让它工作的另一种方式,因为你的帖子提到覆盖乘客类,而不是LayerClass。有趣的是,它对你有效,但对我有限。我将进一步研究这一点,看看为什么我只得到一个结果,我还将检查列表框设置和其他我能找到的东西。现在有点困惑。
Plane objPlane = new Plane();
foreach(DataRow DR in objDS.Tables[0].Rows)
    obj.Plane.Passengers.Add(new Passenger(Int32.Parse(DR["id"].ToString()), DR["name"].ToString()));
this.aListBox.DataSource = objPlane.Passengers; 
this.aListBox.DataValueField = "ID";
this.aListBox.DataTextField = "Name";
this.aListBox.DataBind();