c# - 在 C# 中调用父窗体中的方法和访问父窗体中的 gui 元素的最佳实践

标签 c# winforms

我正在开发一个 win 表单应用程序,我发现自己经常需要访问父表单中的方法,比如来自另一个类的 Form1,无论是表单类还是只是一个类。我的表单 1 的构造函数中有一些初始值设定项,因此我无法创建 Form1 的实例。所以我无法访问 Form1 的方法。

所以我觉得这是一种不好的做法。但是,在某些情况下,我不知道还能做什么,例如考虑这种情况。我有一个名为 ProcessData 的类,其中有一个接收文件、逐行读取并处理数据的方法。现在,我将此方法作为主窗体 Form1 中的线程调用。我的要求是作为数据处理,我想在主窗体 Form1 的多行文本框中显示当前正在处理的行。

之前我所做的一切都在同一个 Form1 中,所以我使用了一个委托(delegate),比如

delegate void SetTextCallback(string text, Control ctrl);
private void SetText(string text, Control ctrl)
    {
        if (ctrl.InvokeRequired)
        {
            SetTextCallback d = new SetTextCallback(SetText);
            this.Invoke(d, new object[] { text, ctrl });
        }
        else
        {
            if (ctrl.GetType() == typeof(Label))
            {
                ctrl.Text = text;
            }
            else
            {
                ctrl.Text += Environment.NewLine + text;
            }
        }
    }

然后我像 SetText("text",Label1); 这样调用它

但如果我从另一个类调用它来引用 Label1,我将需要一个 Form1 的实例,但我将无法创建它,那么最佳做法是什么?

(我知道我可以将文本传递给 SetText 并在那里处理控件,但我将对从不同类调用的各种文本框和标签控件使用同样的东西)

最佳答案

我通常这样做的方式是让子表单公开与该表单上的逻辑操作和事件相对应的事件,例如:

/// <summary>
/// Occurrs when an item is selected in the form
/// </summary>
public event EventHandler<ItemSelectedEventArgs> ItemSelected;

/// <summary>
/// Fires the <see cref="ItemSelected" /> event
/// </summary>
protected void OnItemSelected(MyItem item) 
{
    var handler = this.ItemSelected;
    if (handler != null)
    {
        ItemSelectedEventArgs args = new ItemSelectedEventArgs();
        args.Item = item; // For example
        handler(this, args);
    }
}

这个想法是你的父表单的逻辑应该响应你的子表单上的操作,而不是你的子表单上的操作驱动父表单上的操作 - 你应该尽可能地封装表单逻辑(又名关注点分离)。

此外,作为一种模式,它应该是父/调用表单,它通过 InvokeRequired 等处理将调用编码到正确的线程......而不是子表单 - 这无论如何都是不必要的,除非您正在处理后台线程。

关于c# - 在 C# 中调用父窗体中的方法和访问父窗体中的 gui 元素的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6013343/

相关文章:

C++ Windows 窗体 - If 语句

java - 无法创建 Java 虚拟机 javaw.exe。我的世界

c# - 模型绑定(bind)表单中的可编辑表字段(Razor Pages)

c# - 如何在 Vista 中读取注册表分支 HKEY_LOCAL_MACHINE?

c# - 在列表中选择与界面匹配的项目

c# - 如何从文本框获取值

c# - 将 xml 值映射到枚举类型

c# - 平台目标 (x86/x64/AnyCPU) 对 .net 卫星程序集是否重要

c# - 添加和读取多个文本框

c# - 通过c#和sqlite数据库从数据库中选择一些记录并显示在数据网格中