Binding property to control in Winforms

59,059

Solution 1

You must implement INotifyPropertyChanged And add binding to textbox.

I will provide C# code snippet. Hope it helps

class Sample : INotifyPropertyChanged
{
    private string firstName;
    public string FirstName
    {
        get { return firstName; }
        set
        {
            firstName = value;
            InvokePropertyChanged(new PropertyChangedEventArgs("FirstName"));
        }
    }

    #region Implementation of INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;

    public void InvokePropertyChanged(PropertyChangedEventArgs e)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, e);
    }

    #endregion
}

Usage :

 Sample sourceObject = new Sample();
 textbox.DataBindings.Add("Text",sourceObject,"FirstName");
 sourceObject.FirstName = "Stack"; 

Solution 2

A simplified version of the accepted answer that does NOT require you to type names of properties manually in every property setter like OnPropertyChanged("some-property-name"). Instead you just call OnPropertyChanged() without parameters:

You need .NET 4.5 minimum. CallerMemberName is in the System.Runtime.CompilerServices namespace

public class Sample : INotifyPropertyChanged
{
    private string _propString;
    private int _propInt;


    //======================================
    // Actual implementation
    //======================================
    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
    //======================================
    // END: actual implementation
    //======================================


    public string PropString
    {
        get { return _propString; }
        set
        {
            // do not trigger change event if values are the same
            if (Equals(value, _propString)) return;
            _propString = value;

            //===================
            // Usage in the Source
            //===================
            OnPropertyChanged();

        }
    }

    public int PropInt
    {
        get { return _propInt; }
        set
        {
            // do not allow negative numbers, but always trigger a change event
            _propInt = value < 0 ? 0 : value;
            OnPropertyChanged();
        }
    }
}

Usage stays the same:

var source = new Sample();
textbox.DataBindings.Add("Text", source, "PropString");
source.PropString = "Some new string";

Hope this helps someone.

Share:
59,059
cubski
Author by

cubski

Just another software developer.

Updated on June 28, 2020

Comments

  • cubski
    cubski almost 4 years

    What is the best way to bind a property to a control so that when the property value is changed, the control's bound property changes with it.

    So if I have a property FirstName which I want to bind to a textbox's txtFirstName text value. So if I change FirstName to value "Stack" then the property txtFirstName.Text also changes to value "Stack".

    I know this may sound a stupid question but I'll appreciate the help.

  • Marino Šimić
    Marino Šimić about 13 years
    the post is tagged winforms - is this not for wpf?
  • David
    David about 13 years
    This will update sourceObject when textBox.Text changes. You also need to subscribe to the PropertyChanged event to update the text box contents when sourceObject.FirstName changes (which was the original question).
  • cubski
    cubski about 13 years
    thanks... just a quick question, would this work as two-way binding? when I change the textbox text property, would the firstname property change as well?
  • Stecya
    Stecya about 13 years
    @David - this is working two ways. Just created app and tested it
  • David
    David about 13 years
    @Stecya - OK, sorry (I remember having to do both but that was some time ago).
  • Martin Braun
    Martin Braun over 8 years
    @Stecya This is not entirely correct. Given the above example, it will work when I change sourceObject.FirstName and it will work when I change the text in the textbox in the UI and leave the textbox. However, when I update the text of the textbox in code-behind by doing textbox.Text = "Anything" it will not update the property in the sourceObject. So I think the binding update gets triggered by the .NET on the internal leave event of any control, it's not? Please correct me, when I'm wrong. For me this case is not enough to go with.
  • yatskovsky
    yatskovsky about 8 years
    To bind changes in control to the property, use this textbox.DataBindings.Add("Text",sourceObject,"FirstName", false, DataSourceUpdateMode.OnPropertyChanged);
  • Szybki
    Szybki almost 8 years
    That's nice. Though I suggest using method that automatically gets property name for your convenience: ` protected void OnPropertyChanged() { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(new System.Diagnostics.StackFrame(1).GetMethod().Name.Replace("s‌​et_", ""))); }`
  • Joel Etherton
    Joel Etherton over 7 years
    +1: A note I was not aware of but is obvious after the fact: this will not work with properties not marked as public. It will throw a binding error regarding the dataMember.
  • Admin
    Admin about 6 years
    I'm getting na error on "CallerMemberName". Does it has to be deffined in some place?
  • Steven Bone
    Steven Bone about 6 years
    You need .NET 4.5 minimum. CallerMemberName is in the System.Runtime.CompilerServices namespace
  • Shadowblitz16
    Shadowblitz16 almost 5 years
    [NotifyPropertyChangedInvocator] does not exists even when using .net 4.6.1 and System.Runtime.CompilerServices namespace.
  • ThomasG
    ThomasG almost 5 years