Привязка данных WinForms - PullRequest
       11

Привязка данных WinForms

12 голосов
/ 12 февраля 2010

Я новичок в привязке данных.

У меня есть эти классы:

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

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

И у меня есть List<Foo>

Я хотел бы иметь Foo элементы в ComboBox и Bar элементы в ListBox.Когда я изменяю выбранный элемент в ComboBox, я хочу изменить ListBox.Когда я изменяю выбранный элемент в ListBox, я бы хотел, чтобы TextBox был заполнен BarDesc.

. Следующие работы работают только для ListBox и ComboBox:

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

Теперь я не знаю, как связать выбранное Bar в ListBox свойство TextBox.Text.Может быть, добавление привязки для listBox1 не очень хорошая идея.

Может быть, я должен сделать что-то подобное:

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

Как мне решить мою проблему?

Ответы [ 4 ]

17 голосов
/ 03 марта 2010

Чтобы все это работало, мне пришлось добавить свойство 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");

    }
}
0 голосов
/ 21 апреля 2018

Не по теме о наследовании против композиции.

Вы фактически говорите: «Foo - это список баров, у которых есть имя», когда было бы намного проще сказать «Foo имеет имя и список баров». Но почему?

Что если вы хотите, чтобы у Foo было два списка? Или список и словарь? C # не допускает множественного наследования (что само по себе грязно!), Поэтому вам придется пойти и создать другой класс, который в любом случае будет содержать несколько структур данных.

Также из-за наследования вам пришлось создать метод «Items», который возвращает сам ненужный код.

Попробуйте это:

public class Foo
{
    public string FooName { get; set; }
    public List<Bar> Items;
}
0 голосов
/ 02 марта 2010

Вы, вероятно, должны установить ValueMember в поле со списком. Возможно, вам также потребуется обработать bindingSource.CurrentChanged и заново привязать список к текущему выбранному списку.

0 голосов
/ 02 марта 2010

Используйте 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");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...