Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding a bool property to BackColor Property of a WinForm

I have a Form in my WinForm application, that contains a TextBox and this TextBox bind to FirstName property of a Person Object.

public class Person
{
   string firstName;
   public string FirstName
   {
      get { return firstName; }
      set { 
           firstName = value; 
           this.isOdd = value.Length % 2;
          }
   }

   bool isOdd;  
   public bool IsOdd { get {return isOdd; } }
}

When My application runs, this Form shows and user could types his/her name to the TextBox, How can I bind BackColor property of the Form to the IsOdd Property of Person object(when IsOdd is True BackColor set to Color.Green and when it is False the BackColor set to Color.Red)?

like image 580
Masoud Avatar asked Nov 16 '13 11:11

Masoud


2 Answers

Binding in winforms also has something very similar to wpf. In WPF you have Converter and yes in winforms it's supported by an event called Format. You can try this code:

Binding bind = new Binding("BackColor", person, "IsOdd");
bind.Format += (s, e) => {
   e.Value = (bool)e.Value ? Color.Green : Color.Red;
};
control.DataBindings.Add(bind);

For the class Person, you have to modify it a little. In winforms there is a pattern to notify changes is by using the event with name EventNameChanged together with the raiser named OnEventNameChanged. You can find this pattern is implemented mostly in winforms. You can also use INotifyPropertyChanged which is more familiar in WPF. Here is the modified class:

public class Person {
  string firstName;
  public string FirstName {
     get { return firstName; }
     set {
           firstName = value;
           IsOdd = value.Length % 2 != 0;//Note use IsOdd not isOdd
         }
  }
  bool isOdd;
  public bool IsOdd {
    get { return isOdd; }
    private set { 
         if(isOdd != value){
           isOdd = value;
           OnIsOddChanged(EventArgs.Empty);
         }
    }
    public event EventHandler IsOddChanged;
    protected virtual void OnIsOddChanged(EventArgs e) {
      var handler = IsOddChanged;
      if (handler != null) handler(this, e);
    }        
}

NOTE You can use private set to allow all private code to change the property IsOdd via the setter and notify the changes correctly, using the private variable isOdd won't notify changes unless you have to append some notifying code after that. This code is also Tested!.

like image 129
King King Avatar answered Oct 26 '22 17:10

King King


You can't exactly bind a Color property to bool you'll have to do something like this. Add a readonly property of type Color depends on your boolean and bind it.

internal class MyClass : INotifyPropertyChanged
{
    private bool _isOdd;
    public bool IsOdd 
    {
        get
        {
            return _isOdd;
        }
        set
        {
            _isOdd = value;
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("IsOdd"));
                PropertyChanged(this, new PropertyChangedEventArgs("Color"));
            }
        }
    }

    public Color Color
    {
        get
        {
            return (IsOdd) ? Color.Green : Color.Red;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

Then just bind this class instance to the BackColor property of any control.

control.DataBindings.Add("BackColor", myclass, "Color");

Note: INotifyPropertyChanged interface implementation is must, only then when there is a change in your property that will reflect in bindings immediately.

like image 1
Sriram Sakthivel Avatar answered Oct 26 '22 17:10

Sriram Sakthivel