Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bool as datasource for a CheckBox (Bool update in an other thread than the one it is impacting)

I try to find how to assign a bool to a checkbox. I want that my checkbox.checked value refresh automatically when my bool data change. I know that for ComboBox there are the DataSource attribute that make it with a list but I am not able to find the equivalent with checkbox.

I try with the checkBox.DataBindings but it does not seem to work.On the other hand I don't really know what mean the third attribute.

checkBox.DataBindings.Add("Checked", DisableBugWatcher, "check");

I need that because I have two independent windows that refresh the same checkbox value!

EDIT :

I try to use the Event to update my main GUI but it say : Cross-thread operation not valid: Control 'checkBox' accessed from a thread other than the thread it was created on.

The problem is link to the fact that the bool value is refresh from an other thread than the one that it impact.

like image 457
Othar Avatar asked Mar 06 '13 19:03

Othar


1 Answers

To make DataBindings work, you have to implement INotifyPropertyChange in the class that contains your bool value. If you are hitting myValue from a thread other than the UI thread, you will have to use a SynchronizationContext and initialize myObject in the UI thread.

public class myObject : INotifyPropertyChanged
{
    // The class has to be initialized from the UI thread
    public SynchronizationContext context = SynchronizationContext.Current;

    bool _myValue;
    public bool myValue
    {
        get
        {
            return _myValue;
        }
        set
        {
            _myValue = value;

            // if (PropertyChanged != null)
                // PropertyChanged(this, new PropertyChangedEventArgs("myValue"));

            if (PropertyChanged != null)
            {
                context.Send(
                    new SendOrPostCallback(o => 
                       PropertyChanged(this, new PropertyChangedEventArgs("myValue"))
                    ), null);
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

Then, set your DataBinding as this :

checkBox1.DataBindings.Add("Checked", myObject.GlobalObject, "myValue");

The first parameter is the property of the UI object you want to bind to. The second attribute is your target object instance, the third is the property name of the target object that needs to be bound to the first.

I tried my best to reflect your scenario using a timer that toggle myValue each second (which check the checkbox accordingly). Here is the code of the Form I used:

System.Timers.Timer x = new System.Timers.Timer();
myObject target;

public Form1()
{
    InitializeComponent();

    target = new myObject();

    x.Elapsed += (s, e) =>
        {
            target.myValue = !target.myValue;
        };
    x.Interval = 1000;

    checkBox1.DataBindings.Add("Checked", target, "myValue");

    x.Start();
}
like image 96
Larry Avatar answered Oct 04 '22 01:10

Larry