在静态方法中使用 Winform 对象

本文关键字:Winform 对象 静态方法 | 更新日期: 2023-09-27 18:35:38

我有一个可以忽略很长时间的问题,但现在我必须解决它。
我有 3 个 GUI (Winform) 1 个主要 1 个设置和 1 个用于网络浏览器。
我需要在我的主窗体中调用我的 Web 浏览器窗体中的方法,因此该方法是静态的。

但是,如果我将其设置为静态,如果我尝试使用表单中的对象,它会给我一个错误。

    public partial class Form3 : Form
{
    public Form3()
    {
        InitializeComponent();
    }
    public static void WebLyrics(string url){
        webBrowser1.Navigate(url);
    }
}

在静态方法中使用 Winform 对象

最简单的方法是:

将静态Instance属性添加到 Web 浏览器窗体:

public partial class Form3 : Form
{
    public Form3()
    {
        InitializeComponent();
        Instance = this;
    }
    public static Form3 Instance { get; private set; }
    public void WebLyrics(string url)
    {
        webBrowser1.Navigate(url);
    }
}

并通过另一种形式的 Instance 属性调用 WebLyrics 方法:

public partian class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    private void Navigate() 
    {
        Form3.Instance.WebLyrics("www.stackoverflow.com");
    }
}

我假设您以某种方式在某处创建了这两种形式......

您应该考虑更改代码。为什么您的表单具有静态方法?这没有任何意义。实现它的最简单方法是将对 Web 浏览器窗体的引用传递到主窗体中。或者,您可以在主窗体中实例化 Web 浏览器窗体,然后显示它。

但我建议您引入一种将 UI 与业务逻辑层分离的方法。考虑引入 MVC/MVP 模式,要有明确的分离,然后表单不需要直接相互引用。

解决该问题的最简单(=最少代码)的方法可能是像其他人建议的那样对表单使用单例,或者使用内置表单注册表甚至更简单:

var myForm3 = Application.OpenForms.OfType<Form3>.FirstOrDefault();

我可能更喜欢使用单独的单例来保存表单,因为我会发现它更易于维护。这将更好地分离关注点,因为表单不必创建为单例,并且可以以其他方式重用。真正,应用的 UI 布局才是单一实例。

像这样:

public class AppLayout
{
    public static AppLayout Instance {
        get { ... }
    }
    public WebBrowserForm WebBrowser {get;private set;}
    public MainForm Main {get;private set;}
    public SettingsForm Settings {get;private set;}
}

可以将其视为应用程序单一实例的类型变体。