C# 如何用动作调用?
我总是将表单上的修饰符设置为private,我不喜欢内部或公共 到现在为止,我经常这样调用:C# 如何用动作调用?,c#,winforms,invoke,C#,Winforms,Invoke,我总是将表单上的修饰符设置为private,我不喜欢内部或公共 到现在为止,我经常这样调用: public string Addtext { if(InvokeRequired) { Invoke((MethodInvoker)delegate { textbox.text = value; }); } else textbox.text = value; } 但是为
public string Addtext
{
if(InvokeRequired)
{
Invoke((MethodInvoker)delegate
{
textbox.text = value;
});
}
else
textbox.text = value;
}
但是为表单上的每个成员添加这样的属性完全不是面向对象的
我想创建一个调用参数(操作)的函数。我尽了最大努力,但失败了-它要求表单成员必须是公共的或内部的:(
public void performationform(Action)
{
var form=form.ActiveForm作为FormMain;
对象s=action.Clone();
if(form!=null)
{
形式、行为(行动);
}
}
公共无效履行(诉讼)
{
如果(需要调用)
调用(动作,这个);
其他的
行动(本);
}
我的代码中有两个问题:
它要求我要更改的属性为!=私有:(
如果窗体不在焦点上,则不起作用。如何为需要在窗体范围之外访问或设置的数据添加属性“根本不面向对象?”这实际上是您唯一的选择。在匿名委托(或任何委托)中编写代码在声明该属性的上下文中执行。解决可见性问题的唯一工具是反射,即大的代码气味。创建属性并根据需要使用它们 至于你的第二个选项,我假设你想在你的“主窗体”上执行它。这里有两个选项:假设只有一个实例,并将其作为类的静态属性,在实例构造函数中赋值
public partial class MainForm : Form
{
private static MainForm singletonInstance;
public static MainForm SingletonInstance
{
get { return singletonInstance; }
}
public MainForm() : base()
{
InitializeComponent();
singletonInstance = this;
}
}
public void PerformActionOnForm(Action<FormMain> action)
{
var form = MainForm.SingletonInstance;
// object s = action.Clone(); What was this for?
if (form != null)
{
form.PerformAction(action);
}
}
public分部类MainForm:Form
{
私有静态主窗体;
公共静态主窗体
{
获取{return singletonistance;}
}
public MainForm():base()
{
初始化组件();
singletonistance=这个;
}
}
公共作废绩效表(行动)
{
var form=MainForm.singletonistance;
//对象s=action.Clone();这是干什么用的?
if(form!=null)
{
形式、行为(行动);
}
}
另一种方法只有在所有表单都正确“拥有”并且唯一没有所有者的表单是主表单时才有效。在这种情况下,您可以执行以下操作:
public void PerformActionOnForm(Action<FormMain> action)
{
var form = Form.ActiveForm.TopLevelControl as FormMain;
// object s = action.Clone(); What was this for?
if (form != null)
{
form.PerformAction(action);
}
}
public void performationform(Action)
{
var form=form.ActiveForm.TopLevelControl作为FormMain;
//对象s=action.Clone();这是干什么用的?
if(form!=null)
{
形式、行为(行动);
}
}
对于需要在表单“完全不面向对象”范围之外访问或设置的数据,如何添加属性?这实际上是您唯一的选择。在匿名委托(或任何委托)中编写代码在声明该属性的上下文中执行。解决可见性问题的唯一工具是反射,即大的代码气味。创建属性并根据需要使用它们
至于你的第二个选项,我假设你想在你的“主窗体”上执行它。这里有两个选项:假设只有一个实例,并将其作为类的静态属性,在实例构造函数中赋值
public partial class MainForm : Form
{
private static MainForm singletonInstance;
public static MainForm SingletonInstance
{
get { return singletonInstance; }
}
public MainForm() : base()
{
InitializeComponent();
singletonInstance = this;
}
}
public void PerformActionOnForm(Action<FormMain> action)
{
var form = MainForm.SingletonInstance;
// object s = action.Clone(); What was this for?
if (form != null)
{
form.PerformAction(action);
}
}
public分部类MainForm:Form
{
私有静态主窗体;
公共静态主窗体
{
获取{return singletonistance;}
}
public MainForm():base()
{
初始化组件();
singletonistance=这个;
}
}
公共作废绩效表(行动)
{
var form=MainForm.singletonistance;
//对象s=action.Clone();这是干什么用的?
if(form!=null)
{
形式、行为(行动);
}
}
另一种方法只有在所有表单都正确“拥有”并且唯一没有所有者的表单是主表单时才有效。在这种情况下,您可以执行以下操作:
public void PerformActionOnForm(Action<FormMain> action)
{
var form = Form.ActiveForm.TopLevelControl as FormMain;
// object s = action.Clone(); What was this for?
if (form != null)
{
form.PerformAction(action);
}
}
public void performationform(Action)
{
var form=form.ActiveForm.TopLevelControl作为FormMain;
//对象s=action.Clone();这是干什么用的?
if(form!=null)
{
形式、行为(行动);
}
}
为什么您的表单有这么多可能的入口点可以从其他线程调用?是否执行较低级别的线程封送(表单的控制器可能会有所帮助)而且您不必担心这样的样板代码。为什么您的表单有这么多可能的入口点可以从其他线程调用?线程封送是否降低了级别(表单的控制器可能会有所帮助)您不必担心这样的样板代码。从非UI线程调用UI组件
假设您只有一个消息循环(99%是这样),那么:
访问专用UI组件
访问私有UI成员与访问.NET对象的其他私有成员没有什么不同。这是私有成员的性质,不能从其他对象访问。如果仍要访问,则必须将UI组件的引用传递给调用方,或者使用反射来解析私有对象的路径
将UI组件的引用传递给调用方的示例:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(delegate { MyWorker.Run(button1); });
}
}
class MyWorker
{
public static void Run(Button button)
{
SynchronizedInvoker.Invoke(() => button.Text = "running");
Thread.Sleep(5000); // do some important work here
SynchronizedInvoker.Invoke(() => button.Text = "finished");
}
}
从技术上讲,使用反射是可行的,但并不理想。您需要知道私有成员的路径,这需要有关对象内部的信息。然后,您应该问问自己,为什么首先将其设置为私有的。从非UI线程调用UI组件
假设您只有一个消息循环(99%是这样),那么:
访问专用UI组件
访问私有UI成员与访问.NET对象的其他私有成员没有什么不同。它的性质是不从其他对象访问私有成员。如果
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(delegate { MyWorker.Run(button1); });
}
}
class MyWorker
{
public static void Run(Button button)
{
SynchronizedInvoker.Invoke(() => button.Text = "running");
Thread.Sleep(5000); // do some important work here
SynchronizedInvoker.Invoke(() => button.Text = "finished");
}
}