Thursday, March 3, 2011

.NET Databinding ignores property change

I have written a control in C# that derives from System.Windows.Forms.Control. I have added a property Selected to which I want to databind to a business entity using a BindingSource.

I’ve implemented the PropertyNameChanged pattern by adding a SelectedChanged event that I fire when the Selected property is changed.

This is my code:

public partial class RateControl : Control
{
    [Category("Property Changed")]
    public event EventHandler SelectedChanged;

    public int Selected
    {
      get
      { return m_selected; }
      set
      {
        if (m_selected != value)
        {
          m_selected = value;
          OnSelectedChanged();
          Invalidate();
        }
      }
    }

    protected virtual void OnSelectedChanged()
    {
      if (this.SelectedChanged != null)
        this.SelectedChanged(this, new EventArgs());
    }
}

When I bind to the Selected property, I see the event being subscibed to. The event is also fired when the property changes.

However the business entity is not updated. I don’t even see the getter of the Selected property being accessed.

What am I missing?

From stackoverflow
  • Have you got the binding's update mode set to DataSourceUpdateMode.OnPropertyChanged? Either via binding.DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged;, or using one of the DataBindings.Add(...) overloads.

    The following works for me to push values to the business object...

    using System;
    using System.Diagnostics;
    using System.Windows.Forms;
    
    class MyForm : Form
    {
        public MyForm()
        {
            MyBusinessObject obj = new MyBusinessObject();
            Button btn = new Button();
            btn.Click += delegate { Foo++; };
            DataBindings.Add("Foo", obj, "Bar", false, DataSourceUpdateMode.OnPropertyChanged);
            DataBindings.Add("Text", obj, "Bar");
            Controls.Add(btn);
        }
    
        private int foo;
        public event EventHandler FooChanged;
        public int Foo
        {
            get { return foo; }
            set
            {
                if (foo != value)
                {
                    foo = value;
                    Debug.WriteLine("Foo changed to " + foo);
                    if (FooChanged != null) FooChanged(this, EventArgs.Empty);
                }
            }
        }
    }
    
    class MyBusinessObject
    {
        private int bar;
        public event EventHandler BarChanged;
        public int Bar
        {
            get { return bar; }
            set
            {
                if (bar != value)
                {
                    bar = value;
                    Debug.WriteLine("Bar changed to " + bar);
                    if (BarChanged != null) BarChanged(this, EventArgs.Empty);
                }
            }
        }
    }
    
    static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.Run(new MyForm());
        }
    }
    

0 comments:

Post a Comment