【问题标题】:C# Winforms: Pass a function from one form to another?C# Winforms:将函数从一种形式传递到另一种形式?
【发布时间】:2009-10-01 10:17:54
【问题描述】:

情况:C#、.NET 3.5、WinForms

目标:Form1 有一个可以通过构造函数启用的 Button。 IE。只有当我调用 new Form1(true) 时才会显示该按钮。 我们希望能够通过一些参数从 Form2 向 Form1 传递一个方法(不必在 Form1 的构造函数上),并且当 Form1.Button1 被按下时,Form2.<SomeMethod> 应该被执行。

我们知道我们可以在 Form1 中创建一个委托/事件,然后在 Form2 中执行以下操作:

Form1.SomeDelegate += new ..... (MyMethodInForm2);

...然后在 Form1_ButtonClick 中我们触发事件,该事件反过来会在 Form2 中发挥作用。

但我们想知道是否有更优雅/新/现代的版本(匿名方法?Lambda 表达式?等等)来完成这个。

这个想法是“任何”表单都可以实例化一个 Form1 类并传递它自己的方法以在单击 Form1 的按钮时执行;但不是对调用者的回调(form2,3,..n),Form1 执行传递的函数(它可能驻留在调用者内部)。我们现在真的不需要这些函数有参数。

注意:代码示例包含简单的变量/对象名称,并非取自现实生活,请忽略简单性。

更新抱歉没有更具体,我认为我会继续使用委托/事件模型,但作为参考,我认为以下是对情况的更好描述:

Form1 是一个通用表单,它接受项目列表并显示它们。我们可以传递员工类型或人员类型或任何“T”。它工作正常。 我们收到一个客户的要求,询问是否可以在那个小 Form1 上添加一个可选按钮,如果单击该按钮,它将打开另一个表单/执行某些方法。

这样,如果我使用 Form1,我可以在运行时告诉按钮打开 EmployeeForm,而如果我使用 Form1,同一个按钮可以打开表单 PersonForm。现在打开一个表单并不是我们对该按钮的唯一用途,但这是调用者的问题。

现在,我所做的就是我们所说的:在 Form1 上委托/事件,在“调用”表单上,我们执行 Form1.theEvent += 的东西,以订阅事件。我只是想知道是否有更好的方法来实现这一点,因为这就是我们在 .NET 2.0 中的做法,而我们刚刚开始使用 .NET 3.5。

【问题讨论】:

  • 我想我还想让它对“API”更友好,而不仅仅是让 API 用户知道他必须订阅 XX 事件……

标签: c# .net delegates


【解决方案1】:

听起来你在描述同一件事两次。

订阅事件正是这样做的——将一个函数传递给 Form1,然后在引发事件时执行该函数。

如果需要,您可以使用 lambda 表达式订阅事件,但您不必这样做。

当然,如果您愿意,您可以将委托作为 Form1 构造函数参数,但我认为在这种情况下这样做没有太大优势。

简而言之:我认为正常事件可以满足您的所有需求。如果您需要处理哪些事件,请提供更多信息。

【讨论】:

  • 我猜它的美感取决于 Form1 是否总是使用这种委托。如果是这样,在构造函数中传递一些东西会更美观一些,因为它将需求绑定到 API 中。然而,它是可选的,并且这种形式可以以其他方式使用,然后正如 Jon 所说,没有理由以其他方式这样做。
【解决方案2】:

不完全确定您对表单内容的含义,但您可以发送 Func。例如:

public class MyForm<T>
{

   private readonly Func<T, bool> predicate;

   public MyForm(Func<T, bool> predicate) { this.predicate = predicate }

   private void SomeMethod()
   {
       bool result = predicate();
       // Do something
   }
}

var form = new MyForm(x => x.Number < 5);

【讨论】:

  • 你也可以使用 Action 总是返回 void 或 Predicate 总是返回 bool
【解决方案3】:

第一个:你应该在 Form1 中声明一个公共事件。
第二:您应该调用发送到 Form1 的事件,例如 Button1_Click

【讨论】:

  • Jon,如果他需要在某个特殊时间开始执行此操作,或者不使用它,总是将其作为参数传递或在 lambda 表达式中传递可能会降低速度。
【解决方案4】:

据我所知,Form2 是 Form1 可以更新的非模态对话框。但是可能还没有创建 Form2。

完成更新 Form2 的明显方法是使用事件模型,使用 Composition 并将 Form1 传递到其构造函数中。

您可以使用委托并存储它,但我看不出最好将引用传递给父窗体。

如果您希望 Form2 更新任何类型,那么一个简单的接口就可以解决问题。

【讨论】:

    【解决方案5】:

    另一种方法是通过在通用表单上定义“代理事件”来公开按钮的 Click 事件:

    public class MyForm<T> : Form
    {
    
        public event EventHandler MyClick
        {
            add { this.theButton.Click += value; }
            remove { this.theButton.Click -= value; }
        }
    
        // ...
    }
    

    【讨论】:

      猜你喜欢
      • 2015-06-06
      • 1970-01-01
      • 2015-06-23
      • 2021-08-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多