bool 作为 CheckBox 的数据源(在其他线程中进行 Bool 更新,而不是它影响的线程)
Posted
技术标签:
【中文标题】bool 作为 CheckBox 的数据源(在其他线程中进行 Bool 更新,而不是它影响的线程)【英文标题】:bool as datasource for a CheckBox (Bool update in an other thread than the one it is impacting) 【发布时间】:2013-02-21 19:05:27 【问题描述】:我试图找到如何将布尔值分配给复选框。我希望我的 checkbox.checked 值在我的布尔数据更改时自动刷新。我知道对于 ComboBox 有一个 DataSource 属性,它用一个列表组成,但我找不到复选框的等价物。
我尝试使用 checkBox.DataBindings,但它似乎不起作用。另一方面,我真的不知道第三个属性是什么意思。
checkBox.DataBindings.Add("Checked", DisableBugWatcher, "check");
我需要它,因为我有两个独立的窗口可以刷新相同的复选框值!
编辑:
我尝试使用事件来更新我的主 GUI,但它说:跨线程操作无效:控件'checkBox'从创建它的线程以外的线程访问。
问题在于 bool 值是从其他线程刷新的事实,而不是它影响的线程。
【问题讨论】:
请正确标记您的问题。如果您正在处理 winforms 标记问题winforms
。仅供参考,.net 中有许多 UI 框架,winforms 只是其中之一(顺便说一下,性能较差、可扩展性较差、效率较低的一个)
Bound checkbox does not update its datasource的可能重复
【参考方案1】:
要使 DataBindings 工作,您必须在包含您的 bool 值的类中实现 INotifyPropertyChange。如果您从 UI 线程以外的线程访问 myValue,则必须使用 SynchronizationContext 并在 UI 线程中初始化 myObject。
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;
然后,将您的 DataBinding 设置为:
checkBox1.DataBindings.Add("Checked", myObject.GlobalObject, "myValue");
第一个参数是要绑定的 UI 对象的属性。第二个属性是你的目标对象实例,第三个是需要绑定到第一个的目标对象的属性名。
我已尽力使用每秒切换 myValue 的计时器(相应地选中复选框)来反映您的情况。这是我使用的表单的代码:
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();
【讨论】:
您的答案对于仅在一个线程上运行的程序非常有效。我的问题是我无法通知另一个线程。所以我的程序告诉我:跨线程操作无效:控件'checkBox'从创建它的线程以外的线程访问。有关更多信息,请参阅编辑。 这比看起来更棘手...您必须使用同步上下文并在 UI 线程中实例化 myObject(我在表单构造函数中做了)。然后我使用 Timer 来切换 myValue,从而相应地更新复选框。希望对您有所帮助。 谢谢,因为我的程序做了一点小改动,效果很好!!【参考方案2】:我和朋友一起找到了一种更简单的方法来解决我的问题。我使用表单中的 DialogResult。当我从表单返回时,它给了我按钮单击的状态,它给了我文本框的值。相同的代码适用于我的复选框问题。
以下是代码示例:
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;
【讨论】:
以上是关于bool 作为 CheckBox 的数据源(在其他线程中进行 Bool 更新,而不是它影响的线程)的主要内容,如果未能解决你的问题,请参考以下文章