如何在usercontrol C#中以另一种形式调用mainform方法

时间:2013-07-16 09:02:52

标签: c# winforms

我正在使用c#中的windowsFrom。我试图在用户控件中的一个中调用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();
    }

它将打开另一个,我有一个按钮。当我点击此处的“确定”按钮时,我需要调用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();
    }


   }
 }

任何人都可以帮我解决这个问题。

感谢。

5 个答案:

答案 0 :(得分:3)

快速回答

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

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不是{ {1}}但是UserControl(非常原始,但对于Form,您可以只检查其父表单并将其转换为正确的类型。)

改进

这种引用通常是警报。通常,UI组件不应该如此耦合,并且公共UserControl的方法经常执行某些操作是您Form中有太多逻辑的信号。如何改善这个?

<强> 1。 DECOUPLE CONTROLS 。那么第一步可能是将它们分离一点,只需在Form中添加一个事件并使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

<强> 2。来自控件的DECOUPLE LOGIC 。 UI经常变化,逻辑不变(当它变化时可能不与UI并行)。这只是第一步(现在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(); } 不知道谁将使用它)。下一步(在表单中发生太多事情时执行)是从表单本身中删除这种逻辑。小例子(非常原始),保持TempCalib和以前一样(使用事件)并将TempCalib更改为被动

MainForm

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

public partial class MainForm : Form
{
    public event EventHandler Calibrate;

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

是的,您需要编写更多代码,但这会从UI本身解耦逻辑(例如,对某个操作的响应)。当程序增长时,这将帮助您根据需要更改UI,保持逻辑不知道(并在一个明确定义的位置)。我甚至没有提到这将允许您使用不同的资源(人)来编写逻辑和UI(或重用逻辑用于不同的UI,WinForms和WPF,例如)。无论如何,IMO最明显和最好的回报是...... 可读性:你总能知道逻辑在哪里以及UI管理在哪里,没有搜索,没有混乱,没有错误。

第3。从实施中解决逻辑。您还可以执行更多步骤(需要时)。您的控制器仍然知道具体类型(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(); } } MainForm)。如果您需要在运行时选择不同的表单(例如,要有一个复杂的接口和一个简化的接口或使用依赖注入),那么您必须使用接口解耦控制器。举个例子:

TempCalib

答案 1 :(得分:0)

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

答案 2 :(得分: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();
}

答案 3 :(得分:0)

Form1代码:

    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;

    }

UserControl1代码:

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

    }
}

答案 4 :(得分:-1)

试试这个:

从用户控制中试试这个:

MainForm form = this.TopLevelControl as MainForm;
form.TempCommand();