C# WinForms 数据绑定

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2251075/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 00:46:49  来源:igfitidea点击:

WinForms data binding

c#winformsdata-binding

提问by prostynick

I am new in data binding.

我是数据绑定的新手。

I have those classes:

我有这些课程:

public class Foo : List<Bar>
{
    public string FooName { get; set; }
}

public class Bar
{
    public string BarName { get; set; }
    public string BarDesc { get; set; }
}

And I have a List<Foo>

我有一个 List<Foo>

I would like to have Fooitems in ComboBox, and Baritems in ListBox. When I change selected item in ComboBox, I want ListBoxto change. When I change selected item in ListBoxI would like to have TextBoxfilled with BarDesc.

我想要Foo物品在ComboBoxBar物品在ListBox. 当我更改 中的选定项目时ComboBox,我想ListBox更改。当我更改所选项目时,ListBox我想TextBox填充BarDesc.

Following works only for ListBoxand ComboBox:

以下仅适用于ListBoxComboBox

comboBox1.DataSource = foos;
comboBox1.DisplayMember = "FooName";
listBox1.DataBindings.Add("DataSource", foos, "");
listBox1.DisplayMember = "BarName";

I don't now how to bind selected Barin ListBoxto TextBox.Textproperty. Maybe added binding for listBox1is not a good idea.

我现在不知道如何将 selected Barin绑定ListBoxTextBox.Text属性。也许添加绑定listBox1不是一个好主意。

Maybe I should do something like that:

也许我应该做这样的事情:

((CurrencyManager)listBox1.BindingContext[foos]).CurrentChanged += new EventHandler((o, a) =>
{
    textBox1.DataBindings.Clear();
    textBox1.DataBindings.Add("Text", listBox1.DataSource, "BarDesc");
});

How can I resolve my problem?

我该如何解决我的问题?

采纳答案by AMissico

To make all this work, I had to add the Itemsproperty to the Fooclass. This is the "link/relationship" between the two binding sources.

为了使所有这些工作,我必须将Items属性添加到Foo类中。这是两个绑定源之间的“链接/关系”。

public partial class Form1 : Form {
    public class Foo : List<Bar> {
        public string FooName { get; set; }
        public Foo(string name) { this.FooName = name; }
        public List<Bar> Items { get { return this; } }
    }
    public class Bar {
        public string BarName { get; set; }
        public string BarDesc { get; set; }
        public Bar(string name, string desc) {
            this.BarName = name;
            this.BarDesc = desc;
        }
    }
    public Form1() {

        InitializeComponent();

        List<Foo> foos = new List<Foo>();

        Foo a = new Foo("letters");
        a.Add(new Bar("a", "aaa"));
        a.Add(new Bar("b", "bbb"));
        foos.Add(a);

        Foo b = new Foo("digits");
        b.Add(new Bar("1", "111"));
        b.Add(new Bar("2", "222"));
        b.Add(new Bar("3", "333"));
        foos.Add(b);

        //Simple Related Object List Binding
        //http://blogs.msdn.com/bethmassi/archive/2007/04/21/simple-related-object-list-binding.aspx

        BindingSource comboBoxBindingSource = new BindingSource();
        BindingSource listBoxBindingSource = new BindingSource();

        comboBoxBindingSource.DataSource = foos;
        listBoxBindingSource.DataSource = comboBoxBindingSource;
        listBoxBindingSource.DataMember = "Items";

        comboBox1.DataSource = comboBoxBindingSource;
        comboBox1.DisplayMember = "FooName";

        listBox1.DataSource = listBoxBindingSource;
        listBox1.DisplayMember = "BarName";

        textBox1.DataBindings.Add("Text", listBoxBindingSource, "BarDesc");

    }
}

回答by Stefan

Use BindingSource for all your complex data binding needs:

使用 BindingSource 满足您所有复杂的数据绑定需求:

// bind to List<Foo>
BindingSource comboBoxBindingSource = new BindingSource();
comboBoxBindingSource.DataSource = foos;
// use this binding source in comboBox1
// for display use FooName
comboBox1.DataSource = comboBoxBindingSource;
comboBox1.DisplayMember = "FooName";

// bind to comboBox1's SelectedValue
// it will point to the Foo selected in combobox
BindingSource listBoxBindingSource = new BindingSource();
listBoxBindingSource.DataSource = comboBox1;
listBoxBindingSource.DataMember = "SelectedValue";
// use this binding source in listBox1
// for display use BarName
listBox1.DataSource = listBoxBindingSource;
listBox1.DisplayMember = "BarName";

// bind to comboBox'1s SelectedValue (reusing listBoxBindingSource)
// and set Text to value of BarDesc
textBox1.DataBindings.Add("Text", listBoxBindingSource, "BarDesc");

回答by Big Endian

You should probably set the ValueMember on the combo and the list box. You might need to also handle bindingSource.CurrentChanged and rebind the listbox to the currently selected list.

您可能应该在组合和列表框中设置 ValueMember。您可能还需要处理 bindingSource.CurrentChanged 并将列表框重新绑定到当前选定的列表。

回答by Researcher

Off topic regarding inheritance vs composition.

关于继承与组合的题外话。

You are effectively saying "Foo is a list of bars that has a name", when it would be a lot simpler to say "Foo has a name and has a list of bars". But Why?

您实际上是在说“Foo 是一个有名称的条形列表”,而说“Foo 有一个名称并且有一个条形列表”会简单得多。但为什么?

What if you wanted to make Foo have two lists? Or a List and a Dictionary? C# doesn't allow multiple inheritance (which itself is dirty!), so you would have to go and create another class that holds multiple data structures anyway.

如果你想让 Foo 有两个列表怎么办?还是列表和字典?C# 不允许多重继承(它本身很脏!),因此无论如何您都必须创建另一个包含多个数据结构的类。

Also because of inheritance you had to create an "Items" method that returns itself, unnecessary code.

同样由于继承,您必须创建一个返回自身的“Items”方法,不必要的代码。

Try this:

尝试这个:

public class Foo
{
    public string FooName { get; set; }
    public List<Bar> Items;
}