Привязка выбранного элемента ListBox в присутствии BindingNavigator - PullRequest
1 голос
/ 17 июня 2010

Я пытаюсь привязать данные ListBox SelectedItem к свойству.Следующий код является примером:

using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace BindingFailure
{
 static class Program
 {
  class OuterObject
  {
   public string selected { get; set; }
   public List<string> strings { get; set; }
  }

  public static void Main()
  {
   List<OuterObject> objs = new List<OuterObject>()
   {
    new OuterObject(), new OuterObject()
   };
   objs[0].strings = new List<string> { "one", "two", "three" };
   objs[1].strings = new List<string> { "four", "five", "six" };

   Form form = new Form();

   BindingSource obs = new BindingSource(objs, null),
    ibs = new BindingSource(obs, "strings");
   BindingNavigator nav = new BindingNavigator(obs);
   ListBox lbox = new ListBox();
   lbox.DataSource = ibs;
   lbox.DataBindings.Add(new Binding("SelectedItem", obs, "selected"));

   form.Controls.Add(nav);
   form.Controls.Add(lbox);
   lbox.Location = new System.Drawing.Point(30, 30);

   Application.Run(form);
  }
 }
}

Если вы просто выбираете элемент, двигаетесь вперед, выбираете элемент и затем выходите, он работает как положено.Но если вы переключаетесь назад и вперед между двумя внешними объектами с помощью навигатора, выбранный элемент кажется перезаписанным с неправильным значением.Похоже, что каждый раз, когда BindingNavigator перемещается к элементу, ListBox получает указание перейти к первому элементу в своей коллекции и, таким образом, перезаписывает любое значение, которое раньше было в переменной, связанной с его SelectedItem.

Идеи о том, какчтобы исправить это?Заранее спасибо.

РЕДАКТИРОВАТЬ: Вот архив примера проекта, включая отладочный двоичный файл.

http://www.mediafire.com/?dzmqmz0mynj

РЕДАКТИРОВАТЬ: Вот вспомогательная функция, основанная напринятый ответ:

        public static void Bind(ListControl list, BindingSource outersource, string dataMember)
        {
            Binding bindSel = new Binding("SelectedItem", outersource, dataMember);
            list.DataBindings.Add(bindSel);

            outersource.CurrentChanged += delegate
            {
                list.BeginInvoke(new MethodInvoker(bindSel.ReadValue));
            };
        }

1 Ответ

3 голосов
/ 27 июня 2010

Это происходит потому, что обновление SelectedItem происходит до обновления списка.Таким образом, на первом этапе список не может «принять» значение из другой записи формы, поскольку он не содержит такой записи, а затем он не может восстановить выбор после повторного заполнения элементов списка.

Решение (одно из) состоит в том, чтобы вызвать привязку SelectedItemповторно применить после изменения текущей записи формы.Сначала мы даем привязке имя:

//lbox.DataBindings.Add(new Binding("SelectedIndex", obs, "Index"));
var selItemBinding = new Binding("SelectedItem", obs, "selected");
lbox.DataBindings.Add(selItemBinding);

Чем мы должны повторно применить привязку (обратите внимание, что BeginInvoke необходим для применения привязки после повторного заполнения списка):

obs.CurrentChanged += delegate
{
    form.BeginInvoke(new MethodInvoker(selItemBinding.ReadValue));
};

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

...