【问题标题】:Invoke a method from a form从表单调用方法
【发布时间】:2018-01-15 21:49:51
【问题描述】:

是否可以使用表单中的参数调用方法?我知道我可以使用一个动作。我想闭包会在动作中捕获变量以使其起作用。不过,我觉得方法会更干净。我的代码库中有很多这样的操作,我不喜欢它们隐藏在难以重构的方法中。

    public static void Main()
    {
        Form form = new Form();
        Action action = () => form.SendToBack();//(Now Imagine this Action is 50 lines of code and there's 15 of them...Then it should make sense as to why I want to seperate this logic out into classes and methods.
        //Action action2 = AMethod(form);//doesnt work

        Task.Factory.StartNew(
            () =>
            {                    
                //form.Invoke(AMethod);//doesnt work see error below...also no params
                form.Show();                    
                form.Invoke(action);
                Application.Run();
            }
         );
        Console.Read();
    }

    public static void AMethod(Form form)
    {
        form.SendToBack();
    }

更新
我尝试了每个 cmets form.Invoke(AMethod,form); 的重载,但出现错误:

参数 1:无法从“方法组”转换为“System.Delegate”

【问题讨论】:

  • 在表单中添加一个按钮并对点击事件采取行动? (哎呀误解了这个问题)
  • 有一个重载的Form.Invoke 接受参数参数...
  • 很难说出你想要做什么。您可以只调用AMethod(form);,这将调用表单的SendToBack 方法。此外,如果需要,您可以将参数传递给Invoke
  • @Alex:如果表单是在另一个线程中创建的,那么调用 AMethod(form) 将不起作用,这就是代码所暗示的。你会得到 CrossThreadOperation 异常。
  • @Neolisk - 这是使用Invoke 来避免该异常的关键。

标签: c# winforms


【解决方案1】:

Control.Invoke() 的重载是:

  public Object Invoke(Delegate method)
  public Object Invoke(Delegate method, params Object[] parameters)

第一个参数类型是麻烦制造者,Delegate 是“无类型”委托类型。 C# 编译器坚持您使用类型化委托,以便它可以验证您正在调用具有正确签名的方法。在您的情况下,这意味着您必须传递Action<Form> 类型的委托对象。要求它仅从方法“组”推断委托类型是它不会做的。有点烦人,但类型安全在 C# 中至关重要。

所以正确的语法是:

  form.Invoke(new Action<Form>(AMethod), form);

没有赢得任何奖品。很难传递捕获表单变量的 lambda 语法:

   form.Invoke(new Action(() => AMethod(form)));

匿名方法也可以,但出于同样的原因你必须强制转换:

   form.Invoke((Action)delegate { AMethod(form); });

【讨论】:

    【解决方案2】:

    根据我原始答案中的 cmets,这是一个新的,我相信 OP 正在寻找它。感谢您在转换为 C# 方面的帮助。

    public static void Main()
    {
        Form form = new Form();
        Action action = New Action<Form>(AMethod);
    
        Task.Factory.StartNew(
            () =>
            {                    
                form.Show();                    
                form.Invoke(action, form);
                Application.Run();
            }
         );
        Console.Read();
    }
    
    public static void AMethod(Form form)
    {
        form.SendToBack();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-16
      相关资源
      最近更新 更多