views:

480

answers:

5

How can I Handle MDIParent Form events in childs forms? for example in Parent Form I Have a option "search on child grid" and when that button got clicked, in the child form one row on grid get focused.

Im using C# 3.5 Windows Forms Application

Thanks in Advance

A: 

Have you some code so we can be more helpful?

In any case, you can create your custom events on the child forms, and get the Parent form to suscribe to these events

Jhonny D. Cano -Leftware-
A: 

I'm doing the same kind of thing right now, and here's how I do it:

  • Since the parent is the one raising the event, the event needs to exist on the parent form
  • During the code on the parent that loads the child (you have code somewhere that instantiates the child form), after the child form exists, use AddHandler to tether the event on the MDI parent with a public sub on the child form
  • When the parent form fires the event, the instance of the child form will handle it.

Does this make sense? I'm using VB.NET, so the language may be slightly different, but that's the general technique I'm using.

rwmnau
code snippets please!
Angel Escobedo
+1  A: 

It's not too complicated:

public partial class Form1 : Form
{
    // other stuff...

    // e.g. some button's click event handler
    private void addChild_Click(object sender, EventArgs e)
    {
        Form2 child = new Form2();

        child.MdiParent = this;

        this.SomeEvent += child.SomeMethod();

        // other init stuff...
    }
}

Just make sure the signature of the handler method on the child Forms matches the signature of the event handler delegate of the parent.

One thing to note is if you want only the active child form to respond to the event. In that case you can create a helper extension method like this

public static bool IsActiveMDIChild(this Form child)
{
    Form mdiParent = Form.ActiveForm;

    Form activeChild = mdiParent.ActiveMdiChild;

    return child == activeChild;
}

Then add code like this to the SomeMethod() handler:

public bool SomeMethod(*/ signature here /*)
{
    if(!this.IsActiveMDIChild()) return;

    //do stuff normally, we're in the active child form
}
kek444
This will have the interesting side effect that all loaded instances of Form2 will react on the command; not only the active one.
Fredrik Mörk
You are right, thanks, updated the answer to take that into consideration.
kek444
A: 

In the child form, create a new event for the parent to call:

Friend Event search(ByVal token As String)

In the parent form, declare an instance of the child form withevents:

Private WithEvents _FChild As frmChild

In the parent form, when you want to call the child form, reference your declared variable. The event should appear in intellisense:

Private Sub searchChild_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSearchChild.Click
               _FChild.search(txtToken)
Beth
+4  A: 

I see two different way that I would choose between for this problem.

If you could think of hosting the command in a MenuStrip instead, and it is the same child form that lives in several instances in the MDI application, you could add the command(s) to a MenuStrip control in the child form instead. These menu commands will be automatically merged with the commands in the parent form, but any click events will be carried out in the active child form.

You can control where and how menu commands from the child form merges with the commands in the parent form through the MergeAction and MergeIndex properties. If using this approach you should probably set the Visible property of the MenuStrip in the child form to false to prevent it from taking up unnecessary space on the form.

The second option that I would suggest is to create an interface for defining the search functionality, implement that interface in the child forms that support it, and use the MdiChildActivate event of the MDI parent form to enable or disable the search function based on whether the current child supports it or not.

Simplified code sample of the second approach:

interface IGridSearch
{
    void PerformSearch(string criteria);
}

public partial class MdiChildUI : Form, IGridSearch
{
    public MdiChildUI()
    {
        InitializeComponent();
    }

    public void PerformSearch(string criteria)
    {
        // peform the search
    }        
}

public partial class MdiParentUI : Form
{
    public MdiParentUI()
    {
        InitializeComponent();
    }

    private void MdiParentUI_MdiChildActivate(object sender, EventArgs e)
    {
        SetControlStates();

    }

    private void SetControlStates()
    {
        _searchCommand.Enabled = (this.ActiveMdiChild is IGridSearch);
    }

    private void _searchCommand_Click(object sender, EventArgs e)
    {
        IGridSearch child = (this.ActiveMdiChild as IGridSearch);
        if (child != null)
        {
            child.PerformSearch("whatever to search for");
        }
        else
        {
            MessageBox.Show("Can't search in the active form");
        }
    }
}
Fredrik Mörk
Very clean and easily expendable to other functions.
Justin Drury