views:

87

answers:

1

I have a TextBox and I change it's Left value. And this TextBox is bound to a class that have X property. Now when I change Left value of my TextBox I would like to have X of my class updated. What should i do to force update of my databound class property?

+3  A: 

Because of how data-binding works, this type of 2-way binding will only work if the control advertises changes; usually via a *Changed event - i.e. LeftChanged in this case. Since there is no such event, you simply can't, short of subclassing TextBox, re-declaring (new) Left and adding a LeftChanged that hooks off LocationChanged.

Can you just add an event to LocationChanged and do it manually? Or just update the object manually when you set the location/left?


using System;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    class SuperTextBox : TextBox
    {
        protected override void OnLocationChanged(EventArgs e)
        {
            base.OnLocationChanged(e);

            EventHandler handler = (EventHandler)Events[LeftChangedKey];
            if (handler != null) handler(this, EventArgs.Empty);
        }
        public event EventHandler LeftChanged
        {
            add { Events.AddHandler(LeftChangedKey, value); }
            remove { Events.RemoveHandler(LeftChangedKey, value); }
        }
        public new int Left
        {
            get { return base.Left; }
            set { base.Left = value; }
        }
        private static readonly object LeftChangedKey = new object();
    }
    class Person {
        private int value;
        public int Value {
            get {return value;}
            set {
                this.value = value;
                EventHandler handler = ValueChanged;
                if(handler!=null)
                {
                    handler(this, EventArgs.Empty);
                }
            }
        }
        public event EventHandler ValueChanged;
    }
    static class Program
    {
        static void Main()
        {
            Button btn;
            TextBox txt;
            Person p = new Person { Value = 10 };
            using (Form form = new Form {
                DataBindings = {{ "Text", p, "Value"}},
                Controls = {
                    (txt = new SuperTextBox {
                        DataBindings = {{ "Left", p, "Value", false,
                            DataSourceUpdateMode.OnPropertyChanged}}
                    }),
                    (btn = new Button {
                        Text = "bump",
                        Dock = DockStyle.Bottom
                    })
                }
            }) {
                btn.Click += delegate { txt.Left += 5; };
                Application.Run(form);
            }
        }
    }
}
Marc Gravell
I've derrived from TextBox added new Left and LeftChanged event that is fired when LocationChanged is fired. But still it does not work. Do i miss something?
tomaszs
Yes; the binding must be set to update immediately (onpropertychanged) - I've added an example.
Marc Gravell
Thanks. It works.
tomaszs