2010-01-04 5 views
6

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

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

EDIT для пояснения: при привязке к элементу управления я могу использовать коллекцию DataBindings элемента управления. Однако я ищу способ привязки свойств независимо от исходного и целевого типов.

EDIT: с использованием WinForms

+1

WinForms, WPF или ASP.NET? –

+0

ToolStripButton подразумевает WinForms. –

+0

Извините ... WinForms прав –

ответ

8

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

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

+0

Спасибо за ссылку. Я фактически не использовал Truss, однако он указал мне в правильном направлении, как я мог бы свернуть класс Copmact DataBinding, свой собственный :) –

+0

Можете ли вы показать нам какой-то код? Мне нужно связать одно свойство в двух разных пользовательских классах. – miguelmpn

1

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

Я думаю, что это самый простой способ сделать это.

EDIT: Это только для WPF ...

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

+0

Hmmm INotifyPropertyChanged, похоже, это делает, но это также означает, что мне придется позаботиться о синхронизации между этими двумя, верно? То есть обрабатывать событие PropertyChanged в обоих направлениях. Если это так, на самом деле это не похоже на привязку данных, я думаю ... –

+0

Но эй ... спасибо, что указал мне на этот интерфейс. Это отлично подходит для другой задачи :) Отлично. –

1

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

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

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

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

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

Затем вы должны добавить Binding instances в любой экземпляр BindableToolStripButton.

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

+0

Спасибо, ваш комментарий был очень полезным. Тем не менее, я решил не использовать эту технику, так как есть довольно разные классы, которые должны были бы реализовать эти интерфейсы в моем случае. Поэтому я перевернул свой собственный, основанный на отражении и INotifyPropertyChanged (который проще реализовать, чем IBindableComponent). –

0

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

+0

Спасибо, это отлично выглядит. К сожалению, я только что видел ваш пост, когда закончил свое собственное простое решение. Но я обязательно проверю это, если мне нужны дополнительные функции, спасибо! –

5

Я использую эту пробную версию IBindableComponent на ToolStripButton, найти here. 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"); 
0

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

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 который уведомляет его изменения.

Смежные вопросы