0

我无法最好地描述我的问题的标题,对不起。目前,我使用 Invoke 访问表单上的属性,它运行良好,但我对每个属性都有一个函数,这很不舒服。

    public static void EnableLogin(int enabled)
    {
        var form = Form.ActiveForm as FormMain;
        if (form != null)
            form.EnableLogin = enabled;
    }

    public static void EnableConfirm(int enabled)
    {
        var form = Form.ActiveForm as FormMain;
        if (form != null)
            form.EnableConfirm = enabled;
    }

    public static void EnableRetry(int enabled)
    {
        var form = Form.ActiveForm as FormMain;
        if (form != null)
            form.EnableRetry = enabled;
    }

    public static void EnableTABLogin(int enabled)
    {
        var form = Form.ActiveForm as FormMain;
        if (form != null)
            form.EnableTABLogin = enabled;
    }

这些功能中的每一个看起来都是这样的

    public int EnableLogin
    {
        set
        {
            if (this.InvokeRequired)
            {
                this.Invoke((MethodInvoker)delegate
                {
                    if (value == 0)
                        this.btnLogin.Enabled = false;
                    else
                        this.btnLogin.Enabled = true;
                });
            }
            else
            {
                if (value == 0)
                    this.btnLogin.Enabled = false;
                else
                    this.btnLogin.Enabled = true;
            }
        }
    }

我的问题是,我不能那样做吗

    public static void EnableObject(object name)
    {
        var form = Form.ActiveForm as FormMain;
        if (form != null)
            form.Enable + name = enabled;
    }

绝对不是那样,我想不出更多的面向对象的东西,但是与其用相同的代码编写大量函数,我不能通过传递我想更改的对象来使用一个吗?

4

3 回答 3

2

您可以创建一个方法,该方法接受一个描述要执行的操作的委托参数。然后你可以摆脱重复的代码。

下面是一个示例:我在表单上创建了一个名为 PerformAction 的公共方法。它需要一个 Action<MainForm> 委托作为参数;这个委托描述了应该采取的行动。

应该尽可能使用实例方法,但为了完整起见,我创建了一个从 Form.ActiveForm 获取 Form 实例的静态版本。

代码如下所示:

using System;
using System.Windows.Forms;

namespace WinFormTest
{
    public partial class MainForm : Form
    {
        public void PerformAction(Action<MainForm> action)
        {
            if (InvokeRequired)
                Invoke(action,this);
            else
                action(this);
        }

        public static void PerformActionOnMainForm(Action<MainForm> action)
        {
            var form = ActiveForm as MainForm;
            if ( form!= null)
                form.PerformAction(action);
        }
    }
}

然后可以从另一个线程像这样使用:

    MainForm.PerformActionOnMainForm(form => form.Text = "My form");
    // The action can also be a code block or a method:
    MainForm.PerformActionOnMainForm(form =>
                                         {
                                             form.Width = 200;
                                             form.Height = 300;
                                             form.Left = 100;
                                             form.Top = 200;
                                         });

PerformAction 也可以是通用的,因此您可以在任何表单上使用它。那么签名将是:

public void PerformAction<T>(Action<T> action) 
    where T : Form 
    { 
        ... 
    }

如果您有一个在表单之间共享的公共基类,那么这样声明它是有意义的。或者,您可以创建一个包含该方法的辅助类。

于 2009-04-11T16:01:08.737 回答
0

我问了一个类似的问题,但是对于 WPF,原理是一样的。修改 Jon skeet 为您的问题提供给我的答案,您可以使用以下内容:

public static void InvokeIfNecessary(Form form, MethodInvoker action)
{    
     if (form.InvokeRequired)    
     {        
          form.Invoke(DispatcherPriority.Normal, action);    
     }    
     else    
     {        
          action();    
     }
}

public static void EnableLogin(int enabled)    
{        
    var form = Form.ActiveForm as FormMain;        
    if (form != null)            
        InvokeIfNecessary(form, delegate { form.btnLogin.Enabled = (enabled != 0) });    
}

编辑:从使用 form.Dispatcher 更改。

于 2009-04-11T16:10:12.817 回答
0

您可以将重用的功能移动到两个单独的静态方法(一个扩展)中,这将大大简化您在静态助手和属性中拥有的内容。

public static class FormHelpers
{
  public static void InvokeOnActive<TForm>(Action<TForm> action)
    where TForm : Form
  {
    TForm activeForm = Form.ActiveForm as TForm;
    if (activeForm != null)
      activeForm.InvokeEx(f => { action(f); return f; });
  }
}

public static class ControlExtensions
{
  public static TResult InvokeEx<TControl, TResult>(this TControl control,
                                              Func<TControl, TResult> func)
    where TControl : Control
  {
    if (control.InvokeRequired)
      return (TResult)control.Invoke(func, control);
    else
      return func(control);
  }
}

对于您的财产:

public int EnableLogin
{
  set { this.InvokeEx(f => f.btnLogin.Enabled = value == 0); }
}

对于您的静态助手:

public static void EnableLogin(int enabled)
{
  FormHelpers.InvokeOnActive<FormMain>(f => f.EnableLogin = enabled);
}
于 2009-04-11T17:30:36.183 回答