Выпуск элементов управления привязкой данных на панели инструментов - PullRequest
1 голос
/ 06 февраля 2011

После этого кода ...

var cb = new CheckBox();
var b = new Binding("Text", new Form1.Foo() { Bar = "Hello World!" }, "Bar");
cb.DataBindings.Add(b);
AddCheckBoxToForm(cb);

... Я получаю CheckBox в моей форме с текстом = "". Я ожидал, что текст будет «Hello World!». Foo - это публичный класс в Form1, а Foo.Bar - это свойство с публичным набором get и public, кстати. Что я не понимаю?

:: Обновлено :: Код выше на самом деле работает. Эта проблема возникает только тогда, когда CheckBox находится на ToolStrip. Ниже приведен реальный пример проблемы.

Спасибо.

Ответы [ 4 ]

1 голос
/ 08 марта 2013

У меня была такая же проблема с привязкой к динамически создаваемому ToolStripTextBox. Мое решение немного отличается от тех, которые уже опубликованы здесь, и я думаю, что немного проще.

Мне нужен был класс для размещения динамически создаваемых всплывающих окон на основе ContextMenuStrip. Я включил соответствующие части ниже.

Как показывает сложность, с этим связаны две проблемы. Во-первых, вы должны вручную связать контекст привязки с всплывающим объектом. В моем классе я передаю объект BindingContext из формы хоста в конструктор и присваиваю его всплывающему окну.

Во-вторых, элемент управления TextBox, связанный с ToolStripTextBox, не создается одновременно с созданием ToolStripTextBox (это также относится к динамически создаваемым ToolStripDropdowns). Вместо выполнения предложенной операции Show () / Hide () для принудительного создания элемента управления TextBox я вызываю метод CreateControl () элемента управления TextBox, чтобы принудительно создать его. Мне кажется, что делать это немного чище.

public class DevicePopup
{
    ContextMenuStrip    m_popup;

    public DevicePopup(BindingContext bindingContext)
    {
        m_popup = new ContextMenuStrip();
        m_popup.BindingContext = bindingContext;

        . . .
    }

    public ToolStripTextBox AddTextBox(object dataSource, string dataProperty)
    {
      ToolStripTextBox textBox = new ToolStripTextBox();
      textBox.Control.CreateControl();
      textBox.TextBox.DataBindings.Add("Text", dataSource, dataProperty);

      . . . 
      return textBox;
    }
}
1 голос
/ 07 февраля 2011

Думаю, я нашел вашу проблему. Решение уже эффективно обобщено в первом ответе на этот поток.

Для потомков:

Здесь есть 2 трудности:

  1. Прежде всего, «ToolStripTextBox», прикрепленный к «ToolStripDropDownButton» не может быть действительно создан (ручки и так далее) еще когда мы добавим привязку данных. Данные привязка здесь будет работать только здесь, если элемент управления уже создан. контроль обычно создается, когда это отображается. С другой стороны, для «ToolStipTextBox» прилагается к «ToolStrip» напрямую, это всегда видимый на интерфейсе и, следовательно, это, безусловно, создано. Чтобы обойти это, мы можем используйте следующий код, чтобы заставить создание элемента управления «TextBox» перед добавлением привязки данных.

        this.toolStripDropDownButton1.ShowDropDown();
        this.toolStripDropDownButton1.HideDropDown();
    
  2. Во-вторых, если мы прикрепим «ToolStripTextBox» к «ToolStripDropDownButton», его родитель цепь разорвана. Ты можешь видеть «ToolStipTextBox1.TextBox.Parent» является «System.Windows.Forms.ToolStripDropDownMenu» и его дедушка (например, «ToolStipTextBox1.TextBox.Parent.Parent») нулевой. Поскольку родительская цепочка сломан, TextBox.BindingContext может больше не ссылаются на существующие BindingContext, определенный в основном форма. Следовательно, нам нужно создать свой собственный BindingContext:

         this.toolStripTextBox1.TextBox.BindingContext = new BindingContext();   
    

Таким образом, вы можете попробовать следующий код полностью:

        this.toolStripDropDownButton1.ShowDropDown();
        this.toolStripDropDownButton1.HideDropDown();
        this.toolStripTextBox1.TextBox.BindingContext = new BindingContext();
        this.toolStripTextBox1.TextBox.DataBindings.Add("Text", TableClass.get_TBA().DefaultView, "ID");
1 голос
/ 07 февраля 2011

Большое вам спасибо, Quibblesome!Я могу заменить foreach в моем примере на приведенный ниже, и он работает как положено.Очень мило.

        foreach (var item in list)
        {
            var cb = new CheckBox();
            dropDown.AddControl(cb);

            var b = new Binding("Text", item, "text");
            cb.HandleCreated += delegate(object sender, EventArgs e)
            {
                cb.BindingContext = new BindingContext();
                cb.DataBindings.Add(b);
            };
        }
0 голосов
/ 06 февраля 2011

Я могу избежать DataBinding и использовать System.Reflection в качестве обходного пути, но мне бы очень хотелось узнать, почему мое первое решение не работает.

Это работает:

                foreach (var item in ilist)
                {
                    var cb = new CheckBox();
                    cb.Tag = item;
                    _dropDown.AddControl(cb);

                    //* Todo: Could not get binding to work
                    //var b = new Binding("Text", item, this.DisplayMember);
                    //cb.DataBindings.Add(b);
                    try
                    {
                        cb.Text = item.GetType()
                            .GetProperty(this.DisplayMember ?? string.Empty)
                            .GetValue(item, new object[] { }).ToString();
                    }
                    catch { cb.Text = string.Empty; }

                }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...