Проблемы с реализацией IBindableComponent

#c# #.net #winforms #data-binding

#c# #.net #winforms #привязка данных

Вопрос:

Мне нужно привязать свойство к ToolStripMenuItem. Я поискал вокруг и обнаружил, что это невозможно, лучшим обходным путем, по-видимому, является создание класса BindableToolStripMenuItem и реализация его самостоятельно. Итак, я взял некоторый достаточно хорошо зарекомендовавший себя код из Интернета:

 public class BindableToolStripMenuItem : ToolStripMenuItem,IBindableComponent
{
    private BindingContext bindingContext;
    private ControlBindingsCollection dataBindings;
    [Browsable(false)]
    public BindingContext BindingContext
    {
        get
        {
            if (bindingContext == null)
                bindingContext = new BindingContext();
            return bindingContext;
        }
        set
        {
            bindingContext = value;
        }
    }
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public ControlBindingsCollection DataBindings
    {
        get
        {
            if (dataBindings == null)
                dataBindings = new ControlBindingsCollection(this);
            return dataBindings;
        }
    }
}
  

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

 public partial class Form1 : Form
{
    private Boolean _BindingChecked;
    public Boolean BindingChecked {
        get { return _BindingChecked;  }
        set { _BindingChecked = value; Console.WriteLine(": "   _BindingChecked); }
    }

    public Form1()
    {
        InitializeComponent();

        BindableToolStripMenuItem btsmi = new BindableToolStripMenuItem();
        btsmi.Text = "Checkable";
        btsmi.CheckOnClick = true;
        btsmi.DataBindings.Add(new Binding("Checked",this,"BindingChecked"));

        itemsToolStripMenuItem.DropDownItems.Add(btsmi);
    }
}
  

Хотя это определенно выполняет часть привязки! Если я изменяю строки «Проверено привязкой» или «Checked», это выдает соответствующую ошибку, например:

 An unhandled exception of type 'System.ArgumentException' occurred in System.Windows.Forms.dll

Additional information: Cannot bind to the property or column BindingChecked2 on the DataSource.
  

Просто любые изменения (в любом случае, я тестировал это, реализуя InotifyChanged и в другую сторону) не применяются к связанному свойству.

Есть идеи, где я ошибся? Я так сильно сократил работу, что остались только эти два класса, и я попытался начать с нуля с BdindableToolStripMenuItem и посмотрел на реализацию нескольких других людей (почти все идентичные) и все еще не могу заставить ее работать.

Спасибо

Ответ №1:

Вероятно, вы хотите установить DataSourceUpdateMode привязки на OnPropertyChanged, по умолчанию используется OnValidation, но поскольку пункты меню не имеют нормального поведения фокусировки, я могу предположить, что значение по умолчанию не работает. Это позволяет обновлениям в пункте меню распространяться на свойство BindingChecked

Если вы хотите обратного, обновления свойства BindingChecked с помощью кода для распространения на пункт меню, вы должны реализовать INotifyPropertyChanged в форме и вызывать событие всякий раз, когда вы изменяете свойство из кода (например, в способе доступа к набору свойств).