C # как реализовать привязку данных без контроля? - PullRequest
7 голосов
/ 04 января 2010

Есть ли простой способ реализовать привязку данных, когда ни один из обоих классов не имеет типа Control?

В моем случае я хотел бы привязать переменную к свойству пользовательского ToolStripButton.

РЕДАКТИРОВАТЬ для пояснения: при привязке к элементу управления я могу использовать коллекцию DataBindings элемента управления. Тем не менее, я ищу способ связать свойства независимо от исходного и целевого типов.

РЕДАКТИРОВАТЬ: используя winforms

Ответы [ 6 ]

8 голосов
/ 05 января 2010

Вы, вероятно, можете сделать это, используя Ферма .

Truss обеспечивает привязку данных в стиле WPF для любого класса, который реализует INotifyPropertyChanged. Это дает вам немного больше гибкости, поскольку не ограничивает классы производными от определенного базового класса.

5 голосов
/ 03 февраля 2012

Я использую эту реализацию IBindableComponent на ToolStripButton, найдено здесь . BindableToolStripButton позволяет использовать привязку данных, как с обычным Control.

[ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ToolStrip | ToolStripItemDesignerAvailability.StatusStrip)]
public class BindableToolStripButton : ToolStripButton, IBindableComponent
{

    public BindableToolStripButton()
        : base() { }
    public BindableToolStripButton(String text)
        : base(text) { }
    public BindableToolStripButton(System.Drawing.Image image)
        : base(image) { }
    public BindableToolStripButton(String text, System.Drawing.Image image)
        : base(text, image) { }
    public BindableToolStripButton(String text, System.Drawing.Image image, EventHandler onClick)
        : base(text, image, onClick) { }
    public BindableToolStripButton(String text, System.Drawing.Image image, EventHandler onClick, String name)
        : base(text, image, onClick, name) { }



    #region IBindableComponent Members
    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;
        }
    }
    #endregion

}

Предполагая, что у вас есть класс MyClass, реализующий INotifyPropertyChanged, используйте его так же, как при связывании со свойством элемента управления:

bindableToolStripButton1.DataBindings.Add("Enabled", myClass1, "MyBooleanProperty");
1 голос
/ 05 января 2010

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

Исходя из этой мысли, вы можете создать подкласс ToolStripButton ( или желаемый тип для привязки ) и реализовать IBindableComponent для него.Это работает для всех типов исходных и целевых типов, если они не sealed.Например, кнопка панели инструментов:

public class BindableToolStripButton : ToolStripButton,  IBindableComponent {
    //...

Это приведет к тому, что BindableToolStripButton будет иметь свое собственное свойство .DataBindings, тогда как базовый класс ToolStripButton не имеет такого свойства.

Youпотребуется заполнить детали реализации, используя примеры, показанные здесь от Microsoft для ISite , IBindableComponent , IComponent и любых унаследованных интерфейсов.

Затем вы добавите Связывающие экземпляры к любому экземпляру BindableToolStripButton.

(Примечание: у меня есть только fragements, поэтому я сделаю свою первую публикацию в вики сообщества - и мы увидимчто идет ...)

1 голос
/ 05 января 2010

Используйте свойства зависимостей (ваше свойство в вашем ToolStripButton должно быть) и создайте свойство для вашей переменной в вашем другом классе, а также создайте привязку и установите для нее свойство вашего ToolstripButton.

Полагаю, это самый простой способ сделать это.

РЕДАКТИРОВАТЬ: Это только для WPF ...

Иначе реализуйте INotifyPropertyChanged, и когда ваша переменная изменится, она должна автоматически измениться в вашем ToolStripButton.

0 голосов
/ 11 августа 2015

Существует еще одно быстрое и простое решение, которое заключается в создании свойств в форме и их привязке:

public MyForm : Form
{
    ...

    public bool CanDelete
    { 
        get { return deleteToolStripButton.Enabled; }
        set { deleteToolStripButton.Enabled = value; }
    }

    public MyForm()
    {
        ...
        this.DataBindings.Add("CanDelete", this.MyModel, "DeleteAllowed",
                              false, DataSourceUpdateMode.Never);
        ...
    }
}

Предполагается, что MyModel содержит свойство DeleteAllowed, которое уведомляет о его изменениях.

0 голосов
/ 05 января 2010

Я написал некоторые основные вещи для привязки данных через рефлексию. Он работает на любом объекте и не нуждается в реализации чего-то особенного (нет INotifyPropertyChanged, он просто работает), он является частью моего редактора на http://github.com/filipkunc/opengl-editor-cocoa взгляде на HotChocolate / Bindings (например, повторная реализация Cocoa KVC, KVO в папку .NET). Вы можете увидеть это в действии в проекте HotChocolateTest.

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