每当我在辅助窗体上执行某些操作时,如何让主窗体上的方法在主窗体上执行?

How to get a method on a main form to get executed on the main form whenever i do some action on a secondary form?

每当我更改辅助表单中的某些选项时,我都会尝试更新主表单上的数据。

可能的解决方案:

Form1(主窗体)上创建方法 public,如下所示:

public void updatedata()
{
//data update
}

然后在二级表格上调用它:

Form1.updatedata()

这不起作用,我相信这是因为他正在尝试更新 Form2

我正在使用部分 类,但我不是很了解它们。

public partial class Form1 : Form
{
  public Form1()
  {
  InitializeComponent();
  }
}

第二个:

 public partial class formOpConfig : Form
{
   private Form1 Opener { get; set; }



    public formOpConfig(Form1 opener)
    { //initialize component
    }
}

您似乎在构造函数中传入了对 Form1 对象的引用。使用它:

public partial class formOpConfig : Form
{
    private Form1 Opener { get; set; }

    public formOpConfig(Form1 opener)
    { 
        Opener = opener;
    }

    private void updateForm1()
    {
        Opener.updatedata();
    }
}

Form1 是一个 class,不是对象。如果将 updatedata() 设为 Form1 class 的静态方法,则可以使用 Form1.updatedata(),但这可能与代码的其余部分不兼容。

我觉得肯定有一个重复的问题可以匹配这个问题。但是一直找不到。

鉴于您发布的代码,如果您使用 Opener.updatedata() 而不是 Form1.updatedata(),您的尝试可能会奏效。但这仍然不是最好的解决方案。

评论者 John Saunders 是正确的,正确的做法是在 formOpConfig 中声明一个 event,然后让 Form1 订阅它。看起来更像这样:

public partial class formOpConfig : Form
{
    public event EventHandler UpdateData;

    private void SomethingHappens()
    {
        // do stuff...
        OnUpdateData();
        // maybe do other stuff too...
    }

    private void OnUpdateData()
    {
        EventHandler handler = UpdateData;

        if (handler != null)
        {
            handler(this, EventArgs.Empty);
        }
    }
}

上面声明了一个 event,并在适当的时间(即 SomethingHappens() 时)引发该事件(调用处理程序)。

public partial class Form1 : Form
{
    private void OpenConfigForm()
    {
        OpenConfigForm opConfig = new formOpConfig();

        opConfig.UpdateData += (sender, e) => updatedata();
    }

    // Note that this method is private...no one else should need to call it
    private void updatedata()
    {
        //data update
    }
}

在这里,Form1 在创建 formOpConfig 的实例时订阅事件(我假设 Form1 是创建该实例的对象),并且在调用其处理程序时,它会调用您已经编写的 updatedata() 方法。

这样,两个class就保持解耦;也就是说,它们实际上并不相互依赖,比它们需要的更多(特别是,formOpConfig class 不需要知道任何关于 Form1 的信息)。

一个好的方法是使用 Event.

这允许您解耦表单,因为它们甚至不需要相互引用;基本上,事件是您的第二种形式告诉可能正在收听的人(无需确切知道是谁)发生了有趣的事情,并向他们提供有关他们可以使用的有趣事件的一些信息的一种方式。

The linked article will give you much more detail than the below, which is just a quick idea of how to do it; I would recommend working through the tutorial!

发生这种情况的机制是,任何想了解 Form2 上有趣事件的人都必须订阅 Form2 上的相应事件;然后,每当 Form2 想要告诉它的听众发生了什么事时,它就会调用任何附加到该事件的事件处理程序。

Because an event can have multiple handlers, it's a really excellent way to keep components in your application decoupled.

快速演示

(注意:下面的代码不在头脑中,因此未经测试,没有错误处理等)

首先,您需要声明一个class,可用于将感兴趣的数据发送给监听方。这个 class 必须继承自 System.EventArgs

public class InterestingEventArgs:EventArgs
{
   public string AnInterestingFact {get;private set;}
   public InterestingEventArgs(string fact)
   {
     AnInterestingFact =fact;
   }
}

只要对 Form1Form2 都可见,在哪里声明并不重要。

接下来,您必须在 Form2 上声明一个事件,它需要是 public 并且应该如下所示:

public event EventHandler<InterestingEventArgs> SomethingInterestingHappened;

现在您需要决定何时将此事件告知感兴趣的各方。假设您在 Form2 上有一个按钮,并且您希望在单击它时引发该事件。所以在按钮的 Click 处理程序中,您可能有这样的代码:

public void btnRaiseEvent_Clicked(object sender, EventArgs e)
{
   var fact= txtFact.Text;
   var handler = SomethingInterestingHappened;
   if (handler!=null)
   {
      handler(this,new InterestingEventArgs(fact));
   }
}

最后是当您启动 Form2 时 Form1 的代码可能看起来的样子,假设您单击 Form1 上的按钮以启动 Form2:

public void btnShowForm2_Clicked(object sender, EventArgs e)
{
   var child = new Form2();
   child.SomethingInterestingHappened+=OnSomethingInterestingHappened;
   child.Show();
}

最后,您需要在 Form1 上编写一个事件处理程序,将在引发事件时调用该事件处理程序:

void OnSomethingInterestingHappened(object sender, InterestingEventArgs e)
{
   MessageBox.Show("Did you know? " + e.AnInterestingFact);
}