Как получить доступ к свойствам формы с помощью Invoke, но с параметром объекта в C #? - PullRequest
0 голосов
/ 11 апреля 2009

Я не могу описать название моего вопроса лучше всего, извините. В настоящее время я использую 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;
    }

Это определенно не так, я не мог придумать что-то более ОО, но вместо того, чтобы писать тонны функций с одним и тем же кодом, я не могу использовать одну, передавая объект, который я хочу изменить?

Ответы [ 3 ]

2 голосов
/ 11 апреля 2009

Вы можете создать метод, который принимает параметр делегата, описывающий действие, которое нужно выполнить. Тогда вы можете избавиться от повторного кода.

Вот пример: я создаю публичный метод PerformAction в моей форме. Он принимает делегат Action в качестве аргумента; этот делегат описывает действие, которое следует предпринять.

Метод экземпляра должен использоваться, когда это возможно, но для полноты я создал статическую версию, которая получает экземпляр Form из Form.ActiveForm.

Код выглядит так:

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 
    { 
        ... 
    }

Имеет смысл объявить это следующим образом, если у вас есть общий базовый класс, который используется в ваших формах. Кроме того, вы можете создать вспомогательный класс, содержащий метод.

0 голосов
/ 11 апреля 2009

Вы можете переместить повторно использованную функциональность в два отдельных статических метода (одно расширение), которые значительно упростят то, что вы имеете в статических помощниках и свойствах.

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);
}
0 голосов
/ 11 апреля 2009

Я задал аналогичный вопрос , но для WPF принцип тот же, хотя. Изменив ответ, который дал мне Джон Скит на ваш вопрос, вы можете использовать что-то вроде этого:

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...