0

我正在使用 c# 中的 windowsFrom。我正在尝试在用户控件的 from 之一中调用 mainfrom 方法。我有这样的 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();
    }


   }
 }

任何人都可以帮助我如何做到这一点。

谢谢。

4

5 回答 5

4

快速回答

只需在辅助表单中添加对主要表单的引用:

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_Click不在里面MainForm(但它在里面UserControl),那么您可以将_tempCalib初始化替换为:

_tempCalib = new TempCalib((MainWindow)FindForm());

然后,您将能够调用主要表单:

private void OkButton_Click(object sender, EventArgs e)
{
    _main.TempCommand();  
    this.Hide();
}

注意:这只是一个选项,您可以创建一个属性来保存MainForm引用(因此可以重复使用辅助表单,并且对设计师更友好)而且TempCalib不是一个,UserControl而是一个Form(非常原始,但对于一个UserControl您可以检查它的父级)形成并将其转换为适当的类型)。

改进

这种引用通常是一种警告。通常 UI 组件不应该如此耦合,并且Form经常执行某些事情的公共方法表明您的Form. 如何改善这一点?

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();
    }
}

然后在MainForm

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 partial class MainForm : Form
{
    public event EventHandler Calibrate;

    protected virtual void OnCalibrate(EventArgs e)
    {
        // TODO
    }
}

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

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重用逻辑)。无论如何,IMO 最明显且回报丰厚的好处是……可读性:您将始终知道逻辑在哪里以及 UI 管理在哪里,无需搜索,无需混淆,无需错误。

3. 将逻辑与实现解耦。同样,您还有更多步骤要执行(需要时)。您的控制器仍然知道具体类型(MainFormTempCalib)。如果您需要在运行时选择不同的形式(例如,具有复杂的接口和简化的接口或使用依赖注入),则必须使用接口解耦控制器。只是一个例子:

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

public interface IMainWindow : IUiWindow
{
    event EventHandler Calibrate;
}

public interface ICalibrationWindow : IUiWindow
{
    event EventHandler SomethingMustBeDone;
}
于 2013-07-16T09:08:17.927 回答
0

您在用户控件中创建一个事件并在主窗体中订阅它。这是通常的方式。

于 2013-07-16T09:06:01.493 回答
0

您可以使用在UserControl. 然后你的表单需要处理这个事件并调用你想要调用的方法。如果您让UserControl表单访问您的表单,您将彼此硬链接,这会降低您的UserControl.

例如,在TempCalib

public delegate void OkClickedHandler(object sender, EventArgs e);
public event OkClickedHandler OkClicked;

private void OkButton_Click(object sender, EventArgs e)
{
    // Make sure someone is listening to event
    if (OkClicked == null) return;

    OkClicked(sender, e);

    this.Hide();       
}

在您的主窗体中:

private void Mainform_Load(object sender, EventArgs e)
{
    _tempCalib.OkClicked += CalibOkClicked;
}

private void CalibOkClicked(Object sender, EventArgs e)
{
    StartTemp();
}
于 2013-07-16T09:17:14.793 回答
0

表格 1 代码:

    UserControl1 myusercontrol = new UserControl1();

    public void TabClose(Object sender,EventArgs e)
    {
        int i = 0;
        i = tabControl1.SelectedIndex;
        tabControl1.TabPages.RemoveAt(i);
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        myusercontrol.Dock = DockStyle.Fill;
        TabPage myTabPage = new TabPage();
        myTabPage.Text = "Student";
        myTabPage.Controls.Add(myusercontrol);
        tabControl1.TabPages.Add(myTabPage);
        myusercontrol.OkClick += TabClose;

    }

用户控制1代码:

     public delegate void OkClickedHandler(Object sender, EventArgs e);

public partial class UserControl1 : UserControl
{

    public event OkClickedHandler OkClick;
    public UserControl1()
    {
        InitializeComponent();

    }


    private void button3_Click(object sender, EventArgs e)
    {
        if (OkClick == null) return;
        OkClick(sender, e);

    }
}
于 2014-07-10T12:08:17.843 回答
-1

尝试这个:

从用户控制试试这个:

MainForm form = this.TopLevelControl as MainForm;
form.TempCommand();
于 2013-07-16T09:23:21.017 回答