views:

65

answers:

3

Hi all,

Say I have a global variable INT named X. Since X is global, we can assume that anything can modify its value so it is being changed everytime.

Say I have a Label control named "label". Here's what I want to accomplish:

I want to "bind" the value of label.Text to variable X. In such a way that when variable X is changed, it will be reflected back to label.Text.

Now, I don't want to write event listeners and play with delegates with this one (I want less code as possible). Is there a way to use the DataBinding component for this one? or any other novel techniques?

Thanks, Ian

A: 

Create a property for X. In setter update the label.Text property.

private int _x;
public int X {
    get 
    { 
        return _x; 
    } 
    set 
    { 
        _x = value;
        label.Text = _x.ToString();
    }
}
Krunal
+2  A: 

I don't think you'd be able to bind to a public variable. A variable by itself doesn't have the ability to notify listeners of a change in its value.

That is why you need to wrap the variable in a property. In the setter you raise an event to notify the UI controls that are bound to it, so that they can refresh and display the new value. The framework has a mechanism for this - INotifyPropertyChanged - try this link for a how-to.

Gishu
+2  A: 

If you want to use the Databinding infrastructure, and reflect the changes made to a value, you need a way to notify the UI about the changes made to the binding value.

So the best way to do that is to use a property and implement the INotifyPropertyChanged interface, like this:

class frmFoo : Form, INotifyPropertyChanged
{        
    private string _foo;

    public string Foo
    {
        get { return _foo; }
        set
        {
            _foo = value;
            OnPropertyChanged("Foo");
        }
    }

    protected virtual void OnPropertyChanged(string property)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion
}

Also remember that you need to setup the binding on the label first:

public frmFoo()
    {
        InitializeComponent();

        lblTest.DataBindings.Add(new Binding("Text", this, "Foo"));
    }
iCe
I think this answer is exactly what Ian needs.Maybe it's even better to create a copy of PropertyChanged before checking against null, otherwise it might change to null right before being called, like this:<code> protected virtual void OnPropertyChanged(string property) { var handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(property)); } }</code>(see http://stackoverflow.com/questions/672638/use-of-null-check-in-event-handler/672666#672666 for details)
Simpzon
I agree, that's better reference implementation of the PropertyChanged pattern, with support for multithreaded scenarios.
iCe