Florin C.
Florin C.

Reputation: 366

Call public parent function from child class

Inside my Main method I'm instantiating the UpdateDialog class inside which based on if the user presses a button or not I need to call function1() from Main. Here is the code:

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
  }
}

What should I do to be able to call function1() from Main inside the partial class UpdateDialog?

LE: although the method suggested by Styxxy seems right it doesn't work well in my app because of cross-thread invalid operation so I ended up using the delegate workaround suggested by Cuong Le.

Upvotes: 3

Views: 6022

Answers (8)

Styxxy
Styxxy

Reputation: 7517

You'll have to have an instance of the Main form in your UpdateDialog form. As you say that UpdateDialog is a child form of your Main form, I guess that you create the UpdateDialog in your Main form and do a show there. Before showing that form, you could assign the 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();

You get the error ArgumentException: Top-level control cannot be added to a control.. Now this can be solved in two ways.

  1. You can set the TopLevel property to false on your Main form (I'm not a huge fan of this).
  2. You can use the Owner property to your Main form (this). Below two ways of doing it.

You can set the Owner manually:

updateDialog.Owner = this;

Or you can add this as parameter to the Show(owner) or ShowDialog(owner) methods; this way, the Owner is also being set.

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

"Full" code makes 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)

Upvotes: 15

xray1986
xray1986

Reputation: 1168

You can make your function1 a Partial method and this way you can use it in all your partial classes.

Partial methods allow the definition of a method to be located in one file and the body of the method to be optionally defined in another file. They can only be used in partial classes and were introduced as language features in C# 3.0 and Visual Basic 9.0, the versions that shipped with the .NET Framework 3.5 and Visual Studio 2008.

So what you can do is modify like this

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

Upvotes: -1

sphair
sphair

Reputation: 1670

You could turn it around, and let Main form listen to clicks from the UpdateDialog.

In 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
}

In UpdateDialog:

public event EventHandler OnSomethingHappened;

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

Upvotes: 2

Ekk
Ekk

Reputation: 5715

I suggest you create an event in UpdateDialog then subscribe it after you create an instance inside the Main class. This way you have a better separation between these 2 classes.

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

Upvotes: 4

Tigran
Tigran

Reputation: 62265

Can pass the Main class like a reference.

For example:

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
      }
}

Something like this. You can change this accroding to your precise requirements, but this is a general idea.

Upvotes: 0

awright18
awright18

Reputation: 2333

The ShowDialog() method returns a DialogResult you can call function1 one of after the dialog is closed.

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

Upvotes: 1

Rohit Vats
Rohit Vats

Reputation: 81313

Pass Main class instance to your Update Form and store it in instance variable -

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

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

And from Main method -

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

Upvotes: 3

Konrad Viltersten
Konrad Viltersten

Reputation: 39268

Approach #1

You need to create an instance of class Main.

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

Approach #2

You need to declare the method as static.

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

Upvotes: -1

Related Questions