C# 如何在usercontrol C中调用另一个窗体中的mainform方法#

C# 如何在usercontrol C中调用另一个窗体中的mainform方法#,c#,winforms,C#,Winforms,我正在c#中使用Windows From。我正试图在用户控件中的from中调用mainfrom方法。 我有过这样的经历 namespace Project { public partial class MainForm : Form { public MainForm() { InitializeComponent(); } public void TempCommand() { StartTemp();

我正在c#中使用Windows From。我正试图在用户控件中的from中调用mainfrom方法。 我有过这样的经历

namespace Project
{
  public partial class MainForm : Form
   {
    public MainForm()
    {
        InitializeComponent();
    } 

    public void TempCommand()
      {
       StartTemp();
      }
   }
 }
我在用户控件中单击了按钮。当我点击该按钮时,它将打开另一个表单。我在用户控件中有这样的代码

   private TempCalib _tempCalib = new TempCalib();

   private void calibBtn_Click(object sender, EventArgs e)
    {
        _tempCalib.Show();
    }
它将从中打开另一个,我在其中有一个按钮。当我单击此from中的“Ok”按钮时,我需要调用mainfrom方法

namespace Project
{
public partial class TempCalib : Form
{

    public TempCalib()
    {
        InitializeComponent();
    }

    private void OkButton_Click(object sender, EventArgs e)
    {
       // I need to call the mainfrom "TempCommand" method here.
        this.Hide();
    }


   }
 }
有人能帮我怎么做吗


谢谢。

您可以在usercontrol中创建一个事件,并在mainform中订阅它。
这是通常的方式。

您可以在usercontrol中创建一个事件,并在mainform中订阅它。 这是通常的方法。

快速回答 只需在辅助窗体中添加对主窗体的引用:

public partial class TempCalib : Form
{
    private  MainForm _main

    public TempCalib(MainForm main) : this()
    {
        _main = main;
    }

    /// Other stuffs
}
private TempCalib _tempCalib;
private void calibBtn_Click(object sender, EventArgs e)
{
     if (_tempCalib == null)
         _tempCalib = new TempCalib(this);

     _tempCalib.Show();
}
然后在构造辅助窗体时指定值:

public partial class TempCalib : Form
{
    private  MainForm _main

    public TempCalib(MainForm main) : this()
    {
        _main = main;
    }

    /// Other stuffs
}
private TempCalib _tempCalib;
private void calibBtn_Click(object sender, EventArgs e)
{
     if (_tempCalib == null)
         _tempCalib = new TempCalib(this);

     _tempCalib.Show();
}
如果
calibBtn\u Click
不在
MainForm
内(但在其上的
UserControl
内),则可以将
\u tempCalib
初始化替换为:

_tempCalib = new TempCalib((MainWindow)FindForm());
然后,您可以调用主窗体:

private void OkButton_Click(object sender, EventArgs e)
{
    _main.TempCommand();  
    this.Hide();
}
注意:这只是一个选项,您可以创建一个属性来保存
MainForm
引用(这样第二个表单就可以重用,并且对设计者更加友好),而且
TempCalib
不是
UserControl
而是
form
(非常原始,但对于
UserControl
您只需检查其父窗体并将其转换为适当的类型即可)

改进 这类引用通常是一种警告。通常UI组件不应该如此耦合,而公共
表单执行某些操作的方法通常是表明您的
表单中有太多逻辑。如何改进这一点

1.解耦控件。第一步可能是稍微解耦它们,只需在
TempCalib
中添加一个事件,并使
MainForm
成为其接收器:

public partial class TempCalib : Form
{
    public event EventHandler SomethingMustBeDone;

    private void OkButton_Click(object sender, EventArgs e)
    {
        OnSomethingMustBeDone(EventArgs.Empty); / TO DO
       this.Hide();
    }
}
然后在
main表单中

private TempCalib _tempCalib;
private void calibBtn_Click(object sender, EventArgs e)
{
     if (_tempCalib == null)
     {
         _tempCalib = new TempCalib();
         _tempCalib.SomethingMustBeDone += _tempCalib_SomethingMustBeDone;

         // In _tempCalib_SomethingMustBeDone you'll invoke proper member
         // and possibly hide _tempCalib (remove it from OkButton_Click)
     }

     _tempCalib.Show();
}
2.将逻辑与控件解耦。UI经常更改,而逻辑不会更改(当它更改时可能与UI不并行)。这只是第一步(现在
TempCalib
不知道谁会使用它)。下一步(在表单中发生太多事情时执行)是从表单本身删除此类逻辑。小示例(非常原始),保持
TempCalib
与之前一样(与事件一起),并将
MainForm
更改为被动:

现在,让我们创建一个类来控制流和逻辑:

public class MyTaskController
{
    private MainForm _main;
    private TempCalib _tempCalib;

    public void Start()
    {
        _main = new MainForm();
        _main.Calibrate += OnCalibrationRequested;
        _main.Show(); // Or whatever else
    }

    private void OnCalibrationRequested(object sender, EventArgs e)
    {
        if (_tempCalib == null)
        {
            _tempCalib = new TempCalib();
            _tempCalib.SomethingMustBeDone += OnSomethingMustBeDone();
        }

        _tempCalib.Show();
    }

    private OnSomethingMustBeDone(object sender, EventArgs e)
    {
        // Perform the task here then hide calibration window
        _tempCalib.Hide();
    }    
}
是的,您将需要编写更多的代码,但这将将逻辑(例如,作为对操作的响应)与UI本身分离。当程序长大后,这将帮助您根据需要更改UI,使逻辑不知道这一点(并且在一个定义良好的位置)。我甚至没有提到这将允许您使用不同的资源(人员)来编写逻辑和UI(或者为不同的UI、WinForms和WPF重用逻辑).无论如何,我认为最明显、回报最丰厚的好处是…可读性:您将永远知道逻辑在哪里,UI管理在哪里,没有搜索,没有混乱,没有错误

3.将逻辑与实现解耦。您还需要执行更多步骤(如果需要)。您的控制器仍然知道具体类型(
MainForm
TempCalib
)。以防您需要在运行时选择其他表单(例如,要有一个复杂的接口和一个简化的接口,或者要使用依赖项注入),那么您必须使用接口来解耦控制器。举个例子:

public interface IUiWindow
{
    void Show();
    void Hide();
}

public interface IMainWindow : IUiWindow
{
    event EventHandler Calibrate;
}

public interface ICalibrationWindow : IUiWindow
{
    event EventHandler SomethingMustBeDone;
}
快速回答 只需在辅助窗体中添加对主窗体的引用:

public partial class TempCalib : Form
{
    private  MainForm _main

    public TempCalib(MainForm main) : this()
    {
        _main = main;
    }

    /// Other stuffs
}
private TempCalib _tempCalib;
private void calibBtn_Click(object sender, EventArgs e)
{
     if (_tempCalib == null)
         _tempCalib = new TempCalib(this);

     _tempCalib.Show();
}
然后在构造辅助窗体时指定值:

public partial class TempCalib : Form
{
    private  MainForm _main

    public TempCalib(MainForm main) : this()
    {
        _main = main;
    }

    /// Other stuffs
}
private TempCalib _tempCalib;
private void calibBtn_Click(object sender, EventArgs e)
{
     if (_tempCalib == null)
         _tempCalib = new TempCalib(this);

     _tempCalib.Show();
}
如果
calibBtn\u Click
不在
MainForm
内(但在其上的
UserControl
内),则可以将
\u tempCalib
初始化替换为:

_tempCalib = new TempCalib((MainWindow)FindForm());
然后,您可以调用主窗体:

private void OkButton_Click(object sender, EventArgs e)
{
    _main.TempCommand();  
    this.Hide();
}
注意:这只是一个选项,您可以创建一个属性来保存
MainForm
引用(这样第二个表单就可以重用,并且对设计者更加友好),而且
TempCalib
不是
UserControl
而是
form
(非常原始,但对于
UserControl
您只需检查其父窗体并将其转换为适当的类型即可)

改进 这类引用通常是一种警告。通常UI组件不应该如此耦合,而公共
表单执行某些操作的方法通常是表明您的
表单中有太多逻辑。如何改进这一点

1.解耦控件。第一步可能是稍微解耦它们,只需在
TempCalib
中添加一个事件,并使
MainForm
成为其接收器:

public partial class TempCalib : Form
{
    public event EventHandler SomethingMustBeDone;

    private void OkButton_Click(object sender, EventArgs e)
    {
        OnSomethingMustBeDone(EventArgs.Empty); / TO DO
       this.Hide();
    }
}
然后在
main表单中

private TempCalib _tempCalib;
private void calibBtn_Click(object sender, EventArgs e)
{
     if (_tempCalib == null)
     {
         _tempCalib = new TempCalib();
         _tempCalib.SomethingMustBeDone += _tempCalib_SomethingMustBeDone;

         // In _tempCalib_SomethingMustBeDone you'll invoke proper member
         // and possibly hide _tempCalib (remove it from OkButton_Click)
     }

     _tempCalib.Show();
}
2.将逻辑与控件解耦。UI经常更改,而逻辑不会更改(当它更改时可能与UI不并行)。这只是第一步(现在
TempCalib
不知道谁会使用它)。下一步(在表单中发生太多事情时执行)是从表单本身删除此类逻辑。小示例(非常原始),保持
TempCalib
与之前一样(与事件一起),并将
MainForm
更改为被动:

现在,让我们创建一个类来控制流和逻辑:

public class MyTaskController
{
    private MainForm _main;
    private TempCalib _tempCalib;

    public void Start()
    {
        _main = new MainForm();
        _main.Calibrate += OnCalibrationRequested;
        _main.Show(); // Or whatever else
    }

    private void OnCalibrationRequested(object sender, EventArgs e)
    {
        if (_tempCalib == null)
        {
            _tempCalib = new TempCalib();
            _tempCalib.SomethingMustBeDone += OnSomethingMustBeDone();
        }

        _tempCalib.Show();
    }

    private OnSomethingMustBeDone(object sender, EventArgs e)
    {
        // Perform the task here then hide calibration window
        _tempCalib.Hide();
    }    
}
是的,您将需要编写更多的代码,但这将将逻辑(例如,作为对操作的响应)与UI本身分离。当程序长大后,这将帮助您根据需要更改UI,使逻辑不知道这一点(并且在一个定义良好的位置)。我甚至没有提到这将允许您使用不同的资源(人员)编写逻辑和UI(或重用