如何将数据源链接到另一个数据源中的值?

时间:2012-03-29 13:47:09

标签: c# winforms

我将用WinForms和C#中的一个例子来解释这个问题:

class Foo { List<Bar> Bars { get; } ... }
class Bar { ... }
var foos = new List<Foo>();

首先,我将Foo的列表设置为ListBox的数据源:

var fooListBox = new ListBox();
fooListBox.DataSource = foos;

现在我想要第二个ListBox,其数据源始终是所选 Bar Foo的列表(或null除此以外)。从概念上讲:

var barListBox = new ListBox();
barListBox.DataSource = fooListBox.SelectedValue.Bars;

这个问题有一个简单的解决方案吗?

我目前正在手动连接它:

barListBox.DataSource = fooListBox.SelectedValue != null ? ((Foo)fooListBox.SelectedValue).Bars : null;
fooListBox.SelectedValueChanged += (s,e) => barListBox.DataSource = fooListBox.SelectedValue != null ? ((Foo)fooListBox.SelectedValue).Bars : null;

但我不禁想到我忽略了一些重要的事情。

1 个答案:

答案 0 :(得分:2)

相反,您可以使用BindingSource来保持对象同步。

// first binding source that points to your List of Foos
BindingSource bindingSourceFoos = new BindingSource();
bindingSourceFoos.DataSource = foos;

// create a second binding source that references the first's Bars property
BindingSource bindingSourceBars = new BindingSource(bindingSourceFoos, "Bars");

// set DisplayMember to the property in class Foo you wish to display in your listbox
fooListBox.DisplayMember = "FooName"; // my example, replace with actual name
fooListBox.DataSource = bindingSourceFoos;

// again, set DisplayMember to the property in Bar that you want to display in ListBox
barListBox.DisplayMember = "BarInfo"; // my example, replace with actual name
barListBox.DataSource = bindingSourceBars;

因此,从这一点开始,当您点击FooListBox中的某些内容时,它会自动将BarListBox的内容更改为该Foo的Bar集合。

更新

MSDN - Databinding to a user control

该链接应该告诉您需要知道的所有内容,但以防万一:

像这样装饰你的用户控件:

[System.ComponentModel.LookupBindingProperties
  ("DataSource", "DisplayMember", "ValueMember", "LookupMember")]
public partial class FooSelector : UserControl, INotifyPropertyChanged

将这些成员添加到您的用户控件中:

    public object DataSource
    {
        get
        {
            return fooListBox.DataSource;
        }
        set
        {
            fooListBox.DataSource = value;
        }
    }

    public string DisplayMember
    {
        get { return fooListBox.DisplayMember; }
        set { fooListBox.DisplayMember = value; }
    }

    public string ValueMember
    {
        get { return fooListBox.ValueMember; }
        set
        {
            if ((value != null) && (value != ""))
                fooListBox.ValueMember = value;
        }
    }

    public string LookupMember
    {
        get
        {
            if (fooListBox.SelectedValue != null)
                return fooListBox.SelectedValue.ToString();
            else
                return "";
        }
        set
        {
            if ((value != null) && (value != ""))
                fooListBox.SelectedValue = value;
        }
    }

然后,就像在我的原始示例中一样,您的绑定方式与绑定到普通列表框的方式相同:

// fooSelector1 is your FooSelector user control
fooSelector1.DisplayMember = "Name";
fooSelector1.DataSource = bindingSourceFoos;