以编程方式单击复选框。

7
有没有一种编程方式可以在复选框上生成点击事件?我正在寻找与Button.PerformClick()相当的等效方法。

改变所选属性就像Jeff建议的那样不够吗?你能详细说明一下吗? - Stefan Koell
ASP.net还是Windows Forms? - Fandango68
6个回答

9
为什么需要模拟点击,这行代码不符合你的需求吗?
myCheckBox.Checked = !myCheckBox.Checked;

如果您需要在复选框状态更改时执行逻辑,应该使用CheckedChanged事件而不是Click事件。
private void CheckBox1_CheckedChanged(Object sender, EventArgs e)
{
   MessageBox.Show("You are in the CheckBox.CheckedChanged event.");
}

1
我发布了这个问题,但是问题中说“点击事件”。这不会生成点击事件。 - Matt Breckon
1
也许我会重构控件并使用CheckedChanged事件...无论哪种方式更容易。 - Grzenio
1
请问楼主能否解释一下为什么选择这个答案,因为它实际上并没有回答问题,即如何触发onclick事件?! - Fandango68
1
我推断OP不知道CheckedChanged事件。虽然没有回答他的具体问题,但解决了他根本的意图,即在复选框在程序中被更改时得到通知。 - Jeff Cyr

4

以上解决方案调用了复选框的 CheckedChanged 事件。

如果您想显式调用 Click 事件,可以使用以下代码:

checkBox1_Click(checkBox1, null);

这应该是答案。 - Fandango68
1
这只是调用点击事件处理程序,它不会“生成”点击并且不会更改复选框的值。 - Jeff Cyr

3

您为什么想在复选框上生成点击事件?

如果您想切换它的值:

theCheckBox.Checked = !theCheckBox.Checked;

如果您想触发与单击事件相关联的某些功能,最好将代码从Click事件处理程序移出到一个可以从任何地方调用的单独方法中:

private void theCheckBox_Click(object sender, EventArgs e)
{
    HandleCheckBoxClick((CheckBox)sender);
}

private void HandleCheckBoxClick(CheckBox sender)
{
    // do what is needed here
}

当你像这样设计你的代码时,你可以轻松地从任何地方调用功能:
HandleCheckBoxClick(theCheckBox);

对于大多数控件事件处理程序,可以(并且可能应该)采用相同的方法;尽可能将代码从事件处理程序中移出,并放入更可重用的方法中。


我正在尝试测试一个恶心的表单,该表单在..._Click事件处理程序中启用了一些包含控件。 - Grzenio
1
要小心 - 你不想从CheckBox_Click和CheckBox_CheckedChanged两个事件中调用此方法,因为当复选框被点击时它会被调用两次。 - Philip Wallace
1
@Grzenio:在CheckBox的Click事件中启用/禁用控件不是一个好主意;如果Checked属性由代码分配,那怎么办?这不会触发Click事件,UI将处于不一致状态。你应该让代码作为CheckedChanged事件的结果被执行。 - Fredrik Mörk

1

我还在设置新的工作站,暂时无法进行适当的研究,但是使用UI自动化,也许复选框支持IInvokeProvider,您可以使用Invoke方法吗?


0

ButtonPerformClick() 方法会验证活动控件,测试活动控件是否可以失去当前焦点。对于 CheckBox,有两种可能实现相同功能的方法。第一种方法是使用反射调用 Control 类中的 internal 方法:

public class CheckBoxPerformClick : CheckBox {

    private readonly static MethodInfo callValidateActiveControl;
    private readonly static PropertyInfo propValidationCancelled;

    static CheckBoxPerformClick() {
        try {       
            Type ty = typeof(Control);
            Type outBool = Type.GetType("System.Boolean&");
            callValidateActiveControl = ty.GetMethod("ValidateActiveControl", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[] { outBool }, null);
            propValidationCancelled = ty.GetProperty("ValidationCancelled", BindingFlags.Instance | BindingFlags.NonPublic);
        } catch {}  
    }

    public CheckBoxPerformClick() : base() {
        this.Text = "Checkbox";
        this.Appearance = Appearance.Button;
    }

    public void PerformClick() {
        if (callValidateActiveControl != null && propValidationCancelled != null) {
            try {
                Object[] args = new Object[1];
                bool validate = (bool) callValidateActiveControl.Invoke(this, args);
                bool validatedControlAllowsFocusChange = (bool) args[0];
                if (validate || validatedControlAllowsFocusChange) {
                    bool cancelled = (bool) propValidationCancelled.GetValue(this);
                    if (!cancelled) {
                        ResetFlagsandPaint();
                        OnClick(EventArgs.Empty);
                    }
                }
            } catch {
            }
        }
    }
}

方法二试图做同样的事情,但不使用反射:

public class CheckBoxPerformClick2 : CheckBox {

    public CheckBoxPerformClick2() : base() {
        this.Text = "Checkbox";
        this.Appearance = Appearance.Button;
    }

    public void PerformClick() {
        bool validate = CanPerformClick();
        if (validate) {
            ResetFlagsandPaint();
            OnClick(EventArgs.Empty);
        }
    }

    // before allowing a click, make sure this control can receive the focus, and that other controls don't require validation
    public bool CanPerformClick() { 
        if (!CanSelect)
            return false;

        Control c = this.Parent;
        while (c != null) {
            if (c is ContainerControl)
                break;
            c = c.Parent;
        }

        bool valid = true;
        if (c is ContainerControl) {
            var cc = (ContainerControl) c;
            valid = cc.Validate(true);
        }
        return valid;
    }
}

0

我认为你不能以那种方式生成点击事件,而不直接调用checkBox_Click事件处理程序。但是你可以这样做:

checkBox.Checked = !checkBox.Checked;

即使您这样做,CheckedChanged 处理程序仍将被调用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接