Как связать коллекцию Linq2SQL с текстовыми полями winform

Я немного озадачен тем, как я могу оптимизировать свою программу, используя DataBindings. Моя программа использует несколько связанных объектов Linq2SQL, хранящих данные. Все объекты ORM хранятся в иерархии. Во втором проекте GUI я показываю эти данные в некоторых полях Text и Combo Box.

Иерархия структуры данных выглядит следующим образом:

  • JobManager содержит словарь Jobs
  • Каждое задание содержит словарь Jobitems
  • Каждый Jobitem содержит ровно один Article

Job, Jobitem и Article — это объекты Linq2SQL, представляющие ORM.

Теперь у меня есть графический интерфейс с двумя представлениями списка и панелью вкладок. На панели вкладок отображаются свойства заданий, заданий и статей, а также предлагается возможность изменять задания и задания. Графический интерфейс должен вести себя следующим образом:

  1. Когда в первом ListView выбрано Job, связанные элементы задания будут отображаться во втором ListView, а подробная информация о задании отображается на панели вкладок.
  2. Когда во втором ListView выбрано Jobitem, сведения об элементе задания и сведения о статье отображаются на панели вкладок, но редактировать можно только информацию об элементе задания.
  3. Когда изменения внесены, пользователь должен их намеренно сохранить. В противном случае изменения следует отменить и не синхронизировать с базой данных.

Как я могу добиться такого поведения с помощью DataBinding?

В частности, могу ли я один раз привязать полную коллекцию к одному текстовому полю и перемещаться по его положению, продиктованному выбором в ListViews? Или мне нужно добавлять и удалять отдельные привязки данных для каждого задания для каждого выбора, который делает пользователь?


person Michael Klement    schedule 19.05.2009    source источник
comment
Re ваш комментарий - я добавлю несколько текстовых полей...   -  person Marc Gravell    schedule 19.05.2009


Ответы (1)


Вы действительно имеете в виду "Словарь"? Привязка Winform работает со списками (IList/IListSource), но не со словарем. Кроме того, ListView не так просто привязать, как некоторые другие элементы управления.

Кроме этого, он должен работать исключительно с использованием имен сопоставлений - я попытаюсь сделать простой пример...


Отредактируйте базовый пример из Northwind; обратите внимание, что в идеале контекст данных не должен быть долговечным; вы также можете посмотреть на такие вещи, как реализации репозитория, а не на прямую привязку:

using System;
using System.Windows.Forms;
using SomeNamespaceWithMyDataContext;
static class Program
{
    [STAThread]
    static void Main() {
        MyDataContext ctx = new MyDataContext();
        BindingSource custs = new BindingSource() {
            DataSource = ctx.Customers};

        BindingSource orders = new BindingSource {
            DataMember = "Orders", DataSource = custs};

        Button btn;
        using (Form form = new Form
        {
            Controls = {
                new DataGridView() {
                    DataSource = orders, DataMember = "Order_Details",
                    Dock = DockStyle.Fill},
                new ComboBox() {
                    DataSource = orders, DisplayMember = "OrderID",
                    Dock = DockStyle.Top},
                new ComboBox() {
                    DataSource = custs, DisplayMember = "CompanyName",
                    Dock = DockStyle.Top},                
                (btn = new Button() {
                    Text = "Save", Dock = DockStyle.Bottom
                }), // **edit here re textbox etc**
                new TextBox {
                    DataBindings = {{"Text", orders, "ShipAddress"}},
                    Dock = DockStyle.Bottom
                },
                new Label {
                    DataBindings = {{"Text", custs, "ContactName"}},
                    Dock = DockStyle.Top
                },
                new Label {
                    DataBindings = {{"Text", orders, "RequiredDate"}},
                    Dock = DockStyle.Bottom
                }
            }
        })
        {
            btn.Click += delegate {
                form.Text = "Saving...";
                ctx.SubmitChanges();
                form.Text = "Saved";
            };
            Application.Run(form);
        }
    }
}

В стороне - обратите внимание, что синтаксис:

DataBindings = {{"Text", orders, "ShipAddress"}}

Эквивалентно:

someTextBox.DataBindings.Add("Text", orders, "ShipAddress");

(Я добавляю это только потому, что это общий вопрос)

person Marc Gravell    schedule 19.05.2009
comment
Прежде всего, спасибо за развернутый ответ! Я не знал, что это не работает со словарями, но, увы, словари - это то, что у меня есть из существующего дизайна. Однако я мог бы преобразовать их во временные списки, и как только пользователь нажал кнопку «Сохранить», их можно было бы перенести обратно в словарь для сохранения изменений в базе данных. Это также решило бы мой третий пункт. Что насчет текстовых полей? Как мне привязать текстовый файл к имени одного задания? Один раз с полным списком заданий в качестве источника данных или каждый раз с конкретным заданием под рукой? - person Michael Klement; 19.05.2009
comment
И таким образом я могу отображать отдельные задания в TextField, используя, например. this.BindingContext[custs,ContactName].Position? - person Michael Klement; 19.05.2009
comment
Я не совсем понимаю вопрос; но менеджер валюты для кастомов будет привязан к выбранному кастому; если вам нужен конкретный клиент, просто используйте этот экземпляр клиента непосредственно в источнике привязки... - person Marc Gravell; 19.05.2009