sab*_*669 16 c# checkbox winforms
我看到Checkbox有一个CheckedChanged事件.是否有可能判断它是以编程方式更改,还是由用户实际检查复选框?
我有一个大网格,用户可以在其中键入过滤器,或使用复选框作为一种提供常见过滤参数的"快速过滤器".然后说他们去通过文本框修改过滤器,我正在检查是否应该以编程方式(un)检查CheckBox控件,以便它反映文本框中的过滤器.
private void genericCheckbox_CheckedChanged(object sender, EventArgs e)
{
UpdateFilter();
}
private void UpdateFilter()
{
if (gdcSVNDefaultView.RowCount == 0)
return;
gdcSVNDefaultView.ActiveFilterString = BuildTableFilter();
gdcSVNDefaultView.BestFitColumns();
}
private void gdcSVNDefaultView_ColumnFilterChanged(object sender, EventArgs e)
{
lblTotalFileCount.Text = gdcSVNDefaultView.RowCount.ToString();
if (gdcSVNDefaultView.ActiveFilterString.Contains("Normal"))
cheNormalFiles.Checked = true;
else
cheNormalFiles.Checked = false;
if (gdcSVNDefaultView.ActiveFilterString.Contains("bin") ||
gdcSVNDefaultView.ActiveFilterString.Contains("obj"))
cheBinObjFolders.Checked = true;
else
cheBinObjFolders.Checked = false;
}
Run Code Online (Sandbox Code Playgroud)
通过一些非常轻的测试,这似乎就像我想要的那样工作.但是我担心会出现某种"无限循环"的情况,因为在CheckedChanged事件发生时调用了UpdateFilter方法会触发ColumnFilterChanged事件,这可能会导致CheckedChange再次发生,因为ColumnFilterChanged操作了Checkboxes.
使用flag此目的是确定:
bool suppressCheckedChanged;
private void gdcSVNDefaultView_ColumnFilterChanged(object sender, EventArgs e)
{
suppressCheckedChanged = true;
//.... your own code
//....
suppressCheckedChanged = false;
}
private void genericCheckbox_CheckedChanged(object sender, EventArgs e)
{
if(suppressCheckedChanged) return;
UpdateFilter();
}
Run Code Online (Sandbox Code Playgroud)
flag我认为使用是最好的方法(最简洁方便).但是,在对CheckBox.cs的内部实现进行一些搜索之后,我发现使用了内部字段checkState.该Checked物业的设计只是为了方便.该CheckedChanged活动是在酒店的设置者中提出的CheckState.因此,通过修改checkState字段,我们绕过了CheckedChanged事件提升者.由于该字段checkState不公开,我们必须使用它Reflection来更改其值.这就是为什么这个代码与使用相比有点冗长flag.这是你的代码,请注意,这只是一个参考,以打开这个问题的知识,正如我所说的使用flag更简洁,代码也是连贯的:
//Use this extension method for convenience
public static class CheckBoxExtension {
public static void SetChecked(this CheckBox chBox, bool check){
typeof(CheckBox).GetField("checkState", BindingFlags.NonPublic |
BindingFlags.Instance)
.SetValue(chBox, check ? CheckState.Checked :
CheckState.Unchecked);
chBox.Invalidate();
}
}
//then you can use the SetChecked method like this:
checkBox1.SetChecked(true);//instead of checkBox1.Checked = true;
checkBox1.SetChecked(false);//instead of checkBox1.Checked = false;
Run Code Online (Sandbox Code Playgroud)
我可能会分离然后重新连接处理程序,例如
private void gdcSVNDefaultView_ColumnFilterChanged(object sender, EventArgs e)
{
cheNormalFiles.CheckedChanged -= genericCheckbox_CheckedChanged;
cheBinObjFolders.CheckedChanged -= genericCheckbox_CheckedChanged;
// do stuff...
cheNormalFiles.CheckedChanged += genericCheckbox_CheckedChanged;
cheBinObjFolders.CheckedChanged += genericCheckbox_CheckedChanged;
}
Run Code Online (Sandbox Code Playgroud)