Reputation: 73
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.
Upvotes: 6
Views: 6011
Reputation: 73
I find an easier way with a friend to solve my problem. I use the DialogResult from my form.When I come back from the form it give me the state of the button click and it give me the value of the textbox. The same code works with my checkbox problem.
Here is an exemple of the code :
public partial class MainWindow : Form
{
private OtherWindow m_otherWindow;
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// Lazy create other window if it doesn't exist.
m_otherWindow = m_otherWindow ?? new OtherWindow();
// Passe textbox value to other window.
m_otherWindow.PassedValue=textBox1.Text;
if (m_otherWindow.ShowDialog()==DialogResult.OK)
{
// Clicked ok : update textbox value with textbox value of other window.
textBox1.Text=m_otherWindow.PassedValue;
}
}
private void button2_Click(object sender, EventArgs e)
{
Close();
}
}
public partial class OtherWindow : Form
{
/// <summary>
/// Value to be passed to the window.
/// </summary>
public string PassedValue
{
get { return textBox1.Text; }
set { textBox1.Text = value; }
}
public OtherWindow()
{
InitializeComponent();
}
private void button2_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
}
}
Upvotes: 1
Reputation: 18041
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();
}
Upvotes: 4