在我的C#项目中,我使用以下代码在窗体自己的类之外访问窗体。
public static FormMain singletonInstance { get; private set; }
public static void PFA(Action<FormMain> action) //PFA = PerForm Action
{
var form = FormMain.singletonInstance;
if (form != null)
{
form.PerformAction(action);
}
}
public void PerformAction(Action<FormMain> action)
{
if (InvokeRequired)
Invoke(action, this);
else
action(this);
}"FormMain“中的构造函数是:
public FormMain()
{
InitializeComponent();
singletonInstance = this;
}我不知道用Delphi怎么做。
问题(Delphi):当我在其类Invoke之外时,如何更改表单上的某些内容(例如Edit1.Text)?
提前感谢!
发布于 2009-06-27 17:44:00
调用()操作的需要与调用代码在其类内部或外部无关,必须确保操作控件的方法仅在创建控件的线程上下文中调用。控件具有线程亲和性,这并不是C#或.NET所特有的,它是Windows工作方式所固有的。控件/窗口的消息只能在创建它的线程中处理。这也适用于Delphi,而且整个VCL也不是线程安全的。
与调用()最接近的是Delphi VCL的Synchronize()方法。它在辅助线程中用于调度要在主VCL线程的上下文中执行的代码,主VCL线程是需要在其中创建所有VCL控件的用户界面线程,因此这些控件的所有Windows消息都在其中处理,并且它是唯一真正安全地调用任何控件方法的线程。
Delphi程序本身不会创建任何辅助线程,您必须自己创建。但是,除非您这样做,否则一切都会在主线程上下文中发生,并且不需要调用Synchronize()。您可以简单地调用需要调用的方法。
继续使用您的示例:为编辑控件设置新文本,如下所示:
Form1.Edit1.Text := 'foo bar baz';这里假设包含TForm1类的单元包含一个变量Form1,通常是这样的。这类似于C#代码中的单例。它之所以有效,是因为拖放到窗体上的所有控件都将具有公共可见性。
离题备注
请注意,虽然这是相当常见的代码,但它违反了Law of Demeter。更改窗体中的控件将使随后有必要更改以这种方式访问它们的所有代码。但这完全是另一种讨论。
https://stackoverflow.com/questions/1053203
复制相似问题