[英]How do I access form properties with Invoke, but with object parameter in C#?
對不起,我無法最好地描述我的問題的標題。 目前,我使用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;
}
絕對不是那樣,我想不出更多的面向對象,但是我不是用相同的代碼編寫大量函數,而是通過傳遞我想更改的對象來使用一個嗎?
您可以創建一個使用委托參數來描述要執行的操作的方法。 然后,您可以擺脫重復的代碼。
這是一個示例:我在窗體上創建一個名為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
{
...
}
如果您有一個在表單之間共享的通用基類,則可以這樣聲明它。 或者,您可以創建一個包含該方法的幫助程序類。
我問了一個類似的問題,但是對於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更改。
您可以將重用的功能移動到兩個單獨的靜態方法(一個擴展)中,這將大大簡化您在靜態助手和屬性中的使用。
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);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.