我可以分配给多个基于表单的事件的方法?(Can I assign a method to multi

2019-06-25 23:34发布

我构建一个表格,并有若干的NumericUpDown控制,几个CheckBox控件和一些文本框等每个控件都有所触发一个事件方法(的CheckedChanged,等的ValueChanged),做的东西,但我的主要quesiton是这样的:

我想要做的就是运行,这将我的表格上更新文本字段的单一方法,但目前我有它只是重复24次。 这工作,但我觉得必须有一个更好的办法?下面是我到目前为止的例子。

    private void button3_Click(object sender, EventArgs e)
    {
    // Code Specific to the Buton3_Click
    UpdateTextLabel();
    }
    private void checkBox1_CheckedChanged(object sender, EventArgs e)
    {
    // Code Specific to the checkBox1_CheckChanged
    UpdateTextLabel();
    }
    private void numericUpDown1_ValueChanged(object sender, EventArgs e)
    {
    // numericUpDown1 specific code ....
    UpdateTextLabel();
    }
    private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
    {
    // comboBox1 specific stuff ...
    UpdateTextLabel();
    }
   // .... and so on for every method ....

有没有更好的方式来实现这一目标? 我想说的“如果被点击或改变任何控制...这样做‘UpdateTextLabel()’东西”,但不知道如何去做。 快乐被引导到答案,因为我键入搜索问题似乎并没有成为“正确的问题” ......

谢谢!

Answer 1:

是的,你不希望这样写代码。 你不必,该Application.Idle事件是理想的更新UI的状态。 它运行从消息队列中检索到的所有待决消息的Winforms之后每一次。 因此,保证以后任何您当前订阅的事件来运行。 使它看起来像这样:

    public Form1() {
        InitializeComponent();
        Application.Idle += UpdateTextLabel;
        this.FormClosed += delegate { Application.Idle -= UpdateTextLabel; };
    }

    void UpdateTextLabel(object sender, EventArgs e) {
        // etc..
    }


Answer 2:

是的,任何控制的任何事件可以,只要他们的事件处理程序委托是相同的共享同一个事件处理方法,在这种情况下,这些控件的事件处理程序委托的类型都是“事件处理程序”(没有返回值和2个参数:对象发件人和EventArgs的)。

private void UpdateTextLabel(object sender, EventArgs e)
{
    //your original UpdateTextLabel code here
}

button3.Click += UpdateTextLabel;
checkBox1.CheckedChanged += UpdateTextLabel;
numericUpDown1.ValueChanged += UpdateTextLabel;
comboBox1.SelectedIndexChanged += UpdateTextLabel;


Answer 3:

当然! 您可以使用lambda表达式能够轻松地与未使用的参数处理:

button3.Click += (sender, args) => UpdateTextLabel();
checkBox1.CheckedChanged += (sender, args) => UpdateTextLabel();
numericUpDown1.ValueChanged += (sender, args) => UpdateTextLabel();
comboBox1.SelectedIndexChanged += (sender, args) => UpdateTextLabel();

或者像一些开发商趋势,如果你不关心指定参数时,您可以使用下划线的可读性“忽略”他们:

button3.Click += (_, __) => UpdateTextLabel();
checkBox1.CheckedChanged += (_, __) => UpdateTextLabel();
numericUpDown1.ValueChanged += (_, __) => UpdateTextLabel();
comboBox1.SelectedIndexChanged += (_, __) => UpdateTextLabel();

由于强大的乔恩斯基特一次教育的我来说,这是远远优于默认的Visual Studio命名CONTROLNAME_EVENTNAME的方案,你可以轻松地阅读“按钮3被点击时,更新的文本标签”,或“当ComboBox改变时,更新文字标签”。 这也解放了你的代码文件,消除了一堆无用的方法包装的。 :)

编辑:如果你拥有它重复24次,这似乎是从设计的角度来看有点奇怪。 ...... 再次读啊,妈的。 我错过了评论,你想运行特定的代码,以及更新的文本框中。 嗯,你可以注册一个以上的事件:

button3.Click += (_, __) => SubmitForm();
button3.Click += (_, __) => UpdateTextLabel();

这样做的问题,在技术上 ,事件监听器不保证按顺序开火。 然而,这种简单的情况下(尤其是如果你不使用-= ,并结合事件处理程序),你应该罚款,以保持执行的顺序。 (我假设你需要UpdateTextLabel SubmitForm

或者你可以移动UpdateTextLabel呼叫到您的按钮处理程序:

button3.Click += (_, __) => SubmitForm();

private void SubmitForm(object sender, EventArgs e)
{
    //do submission stuff
    UpdateTextLabel();
}

这有点让您进入同一条船上(尽管有更好的方法命名)。 也许你反而应该移动UpdateTextLabel到一般的“重新绑定”你的表格:

button3.Click += (_, __) => SubmitForm();

private void SubmitForm(object sender, EventArgs e)
{
    //do submission stuff
    Rebind();
}

private void Rebind()
{
    GatherInfo();
    UpdateTextLabel();
    UpdateTitles();
}

这样,如果你要做额外的工作,除了刚刚更新文本标签,所有的代码调用通用Rebind (或任何你想将它命名),并更容易进行更新。

EDITx2:我意识到,另一种选择是使用面向方面的编程。 随着像PostSharp可以佩戴方法来执行它获取编译特殊的代码我99%肯定PostSharp可以让你连接到事件(虽然我从来没有做过专门):

button3.Click += (_, __) => SubmitForm();

[RebindForm]
private void SubmitForm(object sender, EventArgs e)
{
    //do submission stuff
}

[Serializable]
public class RebindFormAttribute : OnMethodBoundaryAspect
{
    public override void OnSuccess( MethodExecutionArgs args )
    {
        MyForm form = args.InstanceTarget as MyForm; //I actually forgot the "InstanceTarget" syntax off the top of my head, but something like that is there
        if (form != null)
        {
            form.Rebind();
        }
    }
}

因此,即使我们没有明确拨打电话随时随地Rebind()属性和面向方面的编程结束运行的额外代码OnSuccess有每当方法被调用成功。



文章来源: Can I assign a method to multiple Form-based Events?