如何从另一个类访问一个窗体的方法,确保它是同一个窗体实例-C#

本文关键字:窗体 方法 确保 -C# 实例 同一个 一个 另一个 访问 | 更新日期: 2023-09-27 17:57:36

更新以更加清晰

我有一个主窗体Form1和一个附加类AslLibForm1包含一个更新其包含的dataGridView控件的方法。AslLib中的一个方法调用此方法。

我的问题是,让AslLib调用Form1的方法的唯一方法是在AslLib的调用方法中创建一个Form1的实例,如下所示:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    public void updateDataGUI(int row, string url, string status, long time)
    {
        Console.WriteLine(status);
        foreach (DataGridViewRow dgvr in dataGridView1.Rows) dgvr.Cells[0].Value = status;
    }
}

static class AslLib
{
    public static async void makeRequest(string url, int row )
    {
        string result;
        Stopwatch sw = new Stopwatch(); sw.Start();
        try
        {
            using (HttpClient client = new HttpClient())
            {
                HttpResponseMessage response = new HttpResponseMessage();
                response = await client.GetAsync(url);
                if (response.IsSuccessStatusCode)
                {
                    result = ((int)response.StatusCode).ToString();
                }
                else
                {
                    result = ((int)response.StatusCode).ToString();
                }
            }
        }
        catch (HttpRequestException hre)
        {
            result = "Server unreachable";
        }
        sw.Stop();
        long time = sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L));

        _form.updateDataGUI(row, url, result, time);
    }
}

我已经尝试在构造函数和方法中传递参数,但由于(我认为makeRequest方法是静态的,编译器会给出错误:

AsyncURLChecker.AslLib._form: cannot declare instance members in a static class              AsyncURLChecker
Static classes cannot have instance constructors                AsyncURLChecker

以上结果是,Form1的方法的Console.WriteLine(status);部分正确地输出了status,但dataGridView没有改变。

我相信,因为我正在创建Form1的新实例,所以我不再引用包含我的dataGridView的原始Form1,而是一个全新的副本,所以它不会更改。

有人能告诉我如何从另一个类操作原始Form1的dataGridView吗?如果可能的话,我的首选方法是调用更新dataGridViewForm1方法,而不是直接从AslLib访问dataGridGiew

如何从另一个类访问一个窗体的方法,确保它是同一个窗体实例-C#

您应该传递对现有表单的引用,而不是创建新表单:

// on Form1
Class1 c1 = new Class1();
c1.DoSomething(this);
// Class1
public void DoSomething(Form1 form)
{
    form.updateDataGUI(row, url, result, time);
}

将表单传递到类构造函数

private Form1 _form;
public Class1(Form1 form)
{
    _form = form;
}

您现在可以从您的班级中访问该表格。

您需要拥有MainForm的原始创建实例。这里有一种方法可以访问它:

Application.OpenForms.OfType<MainForm>().First().updateDataGUI(row, url, result, time);

Application.OpenForms包含当前运行的应用程序的所有打开的表单。)

但是,最好重新设计类结构,以便将MainForm对象的引用传递给类。另一种选择是将实例保存在MainForm本身的静态属性中(如果您确信任何时候都只存在一个实例)。

我认为您可以使用它。

MainForm f = (MainForm)this.Owner;
f.updateDataGUI(row, url, result, time);