7

Is there a simple way to implement databinding when neither of both classes is of type Control?

In my case, I would like to bind a variable to a property of a custom ToolStripButton.

EDIT for clarification: when binding to a Control, I can use Control's DataBindings collection. However, I am searching for a way to bind properties regardless of the source and target Type.

EDIT: using winforms

2
  • ToolStripButton implies WinForms. Commented Jan 4, 2010 at 21:04
  • @bytenik Implies isn't good enough, see there's already one answer relevant only to WPF. Commented Jan 4, 2010 at 21:06

6 Answers 6

8

You can probably do this by using Truss.

Truss provides WPF-style databinding for any class that implements INotifyPropertyChanged. It gives you a bit more flexibility in this, since it doesn't restrict the classes to being derived from a specific base class.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the link. I did not actually use Truss, however it pointed me to the right direction how I could roll a very copmact DataBinding class of my own :)
Can you show us some code? I need to bind one property in two distinct custom classes..
5

I use this Implemetation of IBindableComponent on the ToolStripButton, found here. The BindableToolStripButton allows you to use Databinding like with a normal 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

}

Assuming you have a class MyClass implementing INotifyPropertyChanged, use it just like you would when binding to a control property:

bindableToolStripButton1.DataBindings.Add("Enabled", myClass1, "MyBooleanProperty");

Comments

1

Use dependency properties (your property in your ToolStripButton should be) and create a property for your variable in your other class and create a binding and set it to the property of your ToolstripButton.

I guess that's about the easiest way to do it.

EDIT: That's only for WPF...

Else implement INotifyPropertyChanged and when your variable changes, it should automatically change in your ToolStripButton.

2 Comments

Hmmm INotifyPropertyChanged seems to do this, but this would also mean that I'll have to take care of the synchronisation between those two myself, right? I.e. handle PropertyChanged event in both directions. If so, this would not really be like databinding, I think...
But hey... thanks for pointing me to this Interface. It is perfectly fine for another task :) Great.
1

For similar behaviour like Controls being bound to object properties, for any Type you can implement the same interfaces.

Based on that thought, you can subclass ToolStripButton (or desired Type to have bindings) and implement IBindableComponent for it. This works for all kinds of source and target Types as long as they're not sealed. For example, your tool strip button:

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

This will cause the BindableToolStripButton to have its own .DataBindings property whereas the base ToolStripButton class doesn't have such a propery.

You would need to follow through on filling out implementation details using examples seen here from Microsoft for ISite, IBindableComponent, IComponent and any inherited interfaces.

Then you would add Binding instances to any instance of BindableToolStripButton.

(Note: I only have fragements so will make my first community wiki post - and we'll see how that goes... )

1 Comment

Thank, your comment was very helpful. However, I decided not to use this technique, since there are quite some different classes which would have to implement these interfaces in my case. So I rolled my own, based on reflection and INotifyPropertyChanged (which is easier to implement than IBindableComponent).
0

I written some basic databinding stuff through reflection. It works on any object and doesn't need to implement something special (no INotifyPropertyChanged, it just works) it is part of my editor at http://github.com/filipkunc/opengl-editor-cocoa look at HotChocolate/Bindings (like re-implementation of Cocoa KVC, KVO into .NET) folder. You can see it in action in HotChocolateTest project.

1 Comment

Thank you, this looks great, too. Unfortunately I just saw your post when I had finished my own simple reflection solution. But I will definitely check this out if I need additional features, thanks!
0

There is another quick and simple solution which consists in creating properties in the Form, and bind them:

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);
        ...
    }
}

Assuming that MyModel contains a DeleteAllowed property which notifies its changes.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.