none
Как программно сделать привязку между WPF Combobox и ADO.NET Datatable? RRS feed

  • Вопрос

  • Добрый день.

    Ребята, помогите кто-нибудь, пожалуйста. Мне нужно сделать binding между WPF Combobox и ADO.NET Datatable. Но программно на C#, а не на XAML. У меня есть таблица, назовём её Foods, содержащая следующие поля: Id, Name и Price. Мне нужно, что бы каждый элемент списка визуально отображал только значение из поля Name, но чтобы при выборе элемента списка я мог бы оперировать и значением из Price, которое соответствует выбранному Name.

    Binding myBind = new Binding();
    myBind.Source = Foods;   // Foods это ADO.NET Datatable
    cbxSelectFood.SetBinding(ComboBox.ItemsSourceProperty, myBind);
    cbxSelectFood.SetBinding(ComboBox.DisplayMemberPathProperty, "Name");

    Пока что при просмотре содержимого Combobox'а, его элементами являются не значения из поля Name таблицы Foods, а строки следующего содержания "System.Data.DataRowView". Как сделать, чтобы Combobox показывал то что нужно? Пробовал: myBind.Source = Foods.Rows; но тоже не помогло, просто вместо "System.Data.DataRowView" пишет "System.Data.DataRow".

    P.S. Реализация привязки программным способом мне нужна для того, что у меня в программе есть радиогруппа выбора таблиц. И при выборе в этой радиогруппе я должен переключать Combobox на разные таблицы.


    • Изменено TownSparrow 7 августа 2012 г. 8:34
    7 августа 2012 г. 8:29

Ответы

  • Попробуйте конвертнуть таблицы в cписок (List или ObservableCollection), элементы которого будут иметь вид:

    class Wrapper
    {
       public string DisplayName;
       publid DataRow Value;
    }

    И подлючать уже эти коллекции. Если выяснится, что все арвно долго, то напишити биндинг из XAML, т.к. благодаря декоратору/обертке, у вас для всех таблиц показывать надо будет DisplayName.

    • Помечено в качестве ответа TownSparrow 7 августа 2012 г. 10:51
    7 августа 2012 г. 10:39
    Отвечающий

Все ответы

  • вам нужно не ставить биндинг на DisplayMemberPath а назначить ему значение "Name"

    Combobox1.DisplayMemberPath = "Name";

    7 августа 2012 г. 8:49
  • Сейчас работает, но только приходится очень долго ждать (больше минуты) после выбора нужной радиокнопки переключения списка на соответствующую таблицу. И пока Combobox не переключится - приложение подвешивается. В одной ADO.NET Datatable у меня 164 строки, в другой - 51. Как я уже сказал выше - список переключается очень долго. Ниже привожу обработчики щелчков по радиокнопкам в том виде, как они у меня есть. cbxSelectCompass - это как раз и есть Combobox.

    Щелчок по первой радиокнопке - переходим на таблицу в 164 строки

    private void rbnCompassAsInstrument_Checked(object sender, RoutedEventArgs e)
    {
      if (cbxSelectCompass != null)
      {
        Binding Bind = new Binding();
        Bind.Source = FutSessContentsTable;
        cbxSelectCompass.SetBinding(ComboBox.ItemsSourceProperty, Bind);
        cbxSelectCompass.DisplayMemberPath = "InstrumentName";
      }
    }

    Щелчок по второй радиокнопке - переходим на таблицу в 51 строку.

    private void rbnCompassAsIndex_Checked(object sender, RoutedEventArgs e)
    {
       if (cbxSelectCompass != null)
       {
          Binding Bind = new Binding();
          Bind.Source = RtsIndexTable;
          cbxSelectCompass.SetBinding(ComboBox.ItemsSourceProperty, Bind);
          cbxSelectCompass.DisplayMemberPath = "indexName";
       }
    }

    В обработчике Window_Loaded окна, по умолчанию, устанавливаются условия первой радиокнопки (на таблицу в 164 строки). Но это вряд ли это ест причина медленного переключения. Как можно решить эту проблему. ADO.NET Datatable'ы к БД не подключены. Я их использую просто как коллекции в памяти. Во время использования радиокнопок (переключения между ними) они уже обе полностью заполнены данными. А Combobox почему-то переключается между ними очень медленно.


    7 августа 2012 г. 10:20
  • Попробуйте конвертнуть таблицы в cписок (List или ObservableCollection), элементы которого будут иметь вид:

    class Wrapper
    {
       public string DisplayName;
       publid DataRow Value;
    }

    И подлючать уже эти коллекции. Если выяснится, что все арвно долго, то напишити биндинг из XAML, т.к. благодаря декоратору/обертке, у вас для всех таблиц показывать надо будет DisplayName.

    • Помечено в качестве ответа TownSparrow 7 августа 2012 г. 10:51
    7 августа 2012 г. 10:39
    Отвечающий
  • Хорошо, попробую.

    7 августа 2012 г. 10:52
  • Попробуйте перед тем как создавать новый биндинг убрать предыдущий

    BindingOperations.ClearBinding(cbxSelectCompass, ComboBox.ItemSourceProperty)


    7 августа 2012 г. 10:53
  • Попобую. Я тоже вобще-то думаю, что причина от части в этом.

    7 августа 2012 г. 11:32
  • У меня сейчас времени затык, поэтому я просто пока создал второй Combobox и переключаю их свойство Visibility. Потом разберусь по глубже.

    7 августа 2012 г. 13:12