从子类调用公共父函数

时间:2012-10-24 07:17:56

标签: c# parent-child

在我的Main方法中,我正在实例化UpdateDialog类,其中根据用户是否按下按钮,我需要从function1()调用Main。这是代码:

public partial class Main : Form
{
  public void function1()
  {
    doing_stuff_here();
  }

  private void button1_Click(Object sender, EventArgs e)
  {
    var update = new UpdateDialog();
    update.ShowDialog();
  } 
}

public partial class UpdateDialog : Form
{
  private void button2_Click(object sender, EventArgs e)
  {
    //call here function1() from Main
  }
}

如何从部分班级function1()内的Main拨打UpdateDialog,该怎么办?

LE:虽然Styxxy建议的方法似乎是正确的但由于cross-thread invalid operation我的应用程序效果不佳所以我最终使用了Cuong Le建议的delegate workaround

8 个答案:

答案 0 :(得分:15)

您必须在Main表单中拥有UpdateDialog表单的实例。正如你所说UpdateDialog是你的主窗体的子窗体,我想你在Main窗体中创建UpdateDialog并在那里做一个show。在显示该表单之前,您可以指定Parent property

var updateDialog = new UpdateDialog();
// Or use "UpdateDialog updateDialog = new UpdateDialog();" as people like Andreas Johansson don't like the "var" keyword
// Do other stuff here as well
updateDialog.Parent = this;
// Or use Show() for non modal window
updateDialog.ShowDialog();

您收到错误ArgumentException: Top-level control cannot be added to a control.。现在,这可以通过两种方式解决。

  1. 您可以在主表单上将TopLevel属性设置为false(我不是这方面的忠实粉丝)。
  2. 您可以将Owner属性用于主表单(this)。以下两种方式。
  3. 您可以手动设置Owner

    updateDialog.Owner = this;
    

    或者您可以将this作为参数添加到Show(owner)ShowDialog(owner)方法中;这样,Owner也正在设置中。

    updateDialog.Show(this);
    // or
    updateDialog.ShowDialog(this);
    

    “完整”代码使这个:

    var updateDialog = new UpdateDialog();
    // Do other stuff here as well
    updateDialog.Owner= this;
    updateDialog.ShowDialog(); // or use .Show()
    // or
    updateDialog.ShowDialog(this); // or use .Show(this)
    

答案 1 :(得分:4)

我建议你在UpdateDialog中创建一个事件,然后在Main类中创建一个实例后订阅它。通过这种方式,您可以更好地分离这两个类。

public partial class Main
{
    public void function1()
    {
        doing_stuff_here();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        var update = new UpdateDialog();
        update.OnButton2Click += OnUpdateDialogButton2Click;

        update.ShowDialog();
    }

    void OnUpdateDialogButton2Click(object sender, EventArgs e)
    {
        function1();
    }
}

public partial class UpdateDialog
{
    public event EventHandler<EventArgs> OnButton2Click;

    private void button2_Click(object sender, EventArgs e)
    {
        //call here function1() from Main  

        if (OnButton2Click != null)
        {
            this.OnButton2Click(this, e);
        }
    }
}

答案 2 :(得分:3)

Main类实例传递给Update Form并将其存储在实例变量 -

Main mainWindow = null;
public UpdateDialog(Main mainForm)
{
   mainWindow = mainForm;
}

private void button2_Click(object sender, EventArgs e)
{
   mainWindow.function1();
}

从Main方法 -

private void button1_Click(Object sender, EventArgs e)
{
    var update = new UpdateDialog(this);
    update.ShowDialog();
}

答案 3 :(得分:2)

你可以转过来,让Main表单听取UpdateDialog的点击。

在Main:

private void button1_Click(Object sender, EventArgs e)
{
    var update = new UpdateDialog();
    update.OnSomethingClicked += function1;
    update.ShowDialog();
} 

void form_OnSomethingHappened(object sender, EventArgs e)
{
    // Do the stuff you want
}

在UpdateDialog中:

public event EventHandler OnSomethingHappened;

private void button2_Click(object sender, EventArgs e)
{
     EventHandler handler = OnSomethingHappened;
     if (handler != null) handler(this, e);
}

答案 4 :(得分:1)

ShowDialog()方法返回一个DialogResult,您可以在关闭对话框后调用function1之一。

http://msdn.microsoft.com/en-us/library/c7ykbedk.aspx

答案 5 :(得分:0)

可以将Main类作为引用传递。

例如:

public partial class Main : Form
{
     //make it internal, if UpdateDialog in the same assembly, and it only one that        would use it. In other words hide it for outside world.
     internal void function1()  
     {
         doing_stuff_here();
     }
 ....
}


public partial class UpdateDialog : Form        
{
      private MainForm _main = null;
      public UpdateDialog (MainForm main) { //Accept only MainForm type, _not_ just a Form
        _main = main;
      }

      private void button2_Click(object sender, EventArgs e)
      {
            _main.function1(); //CALL
      }
}

像这样的东西。您可以根据您的具体要求更改此编制,但这是一个大致的想法。

答案 6 :(得分:-1)

方法#1

您需要创建类Main的实例。

Main foo = new Main();
foo.function1();

方法#2

您需要将方法声明为静态。

public static function1(){ ... }
....
Main.function1();

答案 7 :(得分:-1)

你可以让你的function1成为一个部分方法,这样你就可以在所有的部分类中使用它。

部分方法允许将方法的定义放在一个文件中,并且方法的主体可以选择在另一个文件中定义。它们只能在部分类中使用,并作为C#3.0和Visual Basic 9.0(.NET Framework 3.5和Visual Studio 2008附带的版本)中的语言功能引入。

所以你能做的就是像这样修改

public partial class Main : Form

        {
            public partial void function1()
            {
                doing_stuff_here();
            }

            private void button1_Click(object sender, EventArgs e)
            {
                var update = new UpdateDialog();
                update.ShowDialog();
            }   
        }

public partial class UpdateDialog : Form
        {
            public partial void function1();
            private void button2_Click(object sender, EventArgs e)
            {
            function1();
            }
        }