Search code examples
c#.netwinformsdata-binding

WinForms two way bindings don't work when change property value c#


I have this code, and one TextBox control txtTest.

public partial class Form1 : Form
{

    public Test TestProperty { get; set; }

    public Form1()
    {
        InitializeComponent();
        TestProperty = new Test();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        TestProperty.Value = 15;
        txtTest.DataBindings.Add("Text", TestProperty, 
            nameof(TestProperty.Value),false, 
            DataSourceUpdateMode.OnPropertyChanged); // textTest has value 15
        TestProperty.Value = 10; // textTest has value 15
    }
}

public class Test
{
    public int Value { get; set; }
}

On form load I assign value 15 to Value property, after that I add binding for txtTest control on Text property, now my control show txtTest.Text = "15". After binding I assign new value to my Value property 10. Now my txtTest control still shows value 15. If I enter for example 20 in my text box control via form I have value 20 in property Value.

For this case why I don't have value 10 in my txtTest.Text property?


Solution

  • To support two-way databinding for your business objects, you need to raise change notification when data in your object changes. To do so, you can use either of the following options:

    • You can implement INotifyPropertyChanged for your class. (✔ Preferred)

    • Or you can implement [PropertyName]Changed pattern for you property; assuming you have XXXX property, then you need to have XXXXChanged event in your class.

    To learn more about data binding and change notification, take a look at the following documentations:

    You can find a more useful documentations in the following doc:

    Example - Implement INotifyPropertyChanged

    using System;
    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    public class Customer : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        string firstName;
        public string FirstName
        {
            get { return firstName; }
            set {
                if (value != firstName) {
                    firstName = value;
                    NotifyPropertyChanged();
                }
            }
        }
        string lastName;
        public string LastName
        {
            get { return lastName; }
            set {
                if (value != lastName) {
                    lastName = value;
                    NotifyPropertyChanged();
                }
            }
        }
    }
    

    Example 2 - Apply [PropertyName]Changed pattern

    using System;
    public class Customer 
    {
        public event EventHandler FirstNameChanged;
        public event EventHandler LastNameChanged;
        protected void OnFirstNameChanged(EventArgs e)
        {
            FirstNameChanged?.Invoke(this, e);
        }
        protected void OnLastNameChanged(EventArgs e)
        {
            LastNameChanged?.Invoke(this, e);
        }
        string firstName;
        public string FirstName
        {
            get { return firstName; }
            set {
                if (value != firstName) {
                    firstName = value;
                    OnFirstNameChanged(EventArgs.Empty);
                }
            }
        }
        string lastName;
        public string LastName
        {
            get { return lastName; }
            set {
                if (value != lastName){
                    lastName = value;
                    OnLastNameChanged(EventArgs.Empty);
                }
            }
        }
    }