This is a migrated thread and some comments may be shown as answers.

Closing an MDI Child Form

13 Answers 841 Views
Dock
This is a migrated thread and some comments may be shown as answers.
Dragoljub
Top achievements
Rank 1
Dragoljub asked on 22 May 2008, 11:32 AM
Hello,

I have forms inside document panes. The panes are created automatically for each MDI child form. I don't understand why document panes are working with form events. Isn't it logical that the little X button in the top right corner of the document pane causes the form to close? As a replacement for the normal close button of the form. If I don't want the form to close, just hide, I can always intercept the FormClosing event and cancel it, right?

The way it works now is very bad:
1) When I manually call the form Close method , the form closes, but the pane stays open. It should close as well since it is obviously not needed anymore.
2) When I click the document pane's X button it disappears, but the FormClosing/FormClosed events do not fire.

I've also read another post related to Activate and Deactivate events not firing and you say it's by design. I don't understand why it should be this way. Without the proper plumbing I have to write a lot more complicated code just to do all this basic stuff.

Can't you extend the document pane logic to support MDI child forms better? If not, is there another solution?

13 Answers, 1 is accepted

Sort by
0
Julian Benkov
Telerik team
answered on 22 May 2008, 01:19 PM
Hello Dragoljub,

We are unable to provide workarounds to the form closing and events issues. Addressing these issues will happen within a larger context of a redesign of the docking component. We will be investing more effort in this component for our Q2 2008 release. Our goal is to resolve high-priority issues for the RadDock component.

All the issues you have reported have been logged to our TODO list.

I'm sorry I'm unable to offer you more at this time. Please contact me with any other questions you have about our product. Your Telerik points have been updated.

All the best,
Julian Benkov
the Telerik team

Instantly find answers to your questions at the new Telerik Support Center
0
Dragoljub
Top achievements
Rank 1
answered on 22 May 2008, 02:21 PM
Protected Function ShowMyForm(Of FormType As {New, Form})() As FormType 
    Dim f As FormType = New FormType() 
    f.MdiParent = Me 
    f.Show() 
    AttachHandlerForDocumentPaneClosed(f) 
    Return f 
End Function 
 
Protected Sub AttachHandlerForDocumentPaneClosed(ByVal f As Form) 
    Dim pane As DocumentPane = CType(f.Parent, DocumentPane) 
    AddHandler pane.Closed, AddressOf Me.documentPane_Closed 
End Sub 
 
Private Sub documentPane_Closed(ByVal sender As ObjectByVal e As EventArgs) 
    Dim pane As DocumentPane = CType(sender, DocumentPane) 
    If pane.Controls.Count > 0 Then 
        CType(pane.Controls(0), Form).Close() 
    End If 
End Sub 

Thanks for the points :)

As you can see (in the mdi container code above) I found a way
to do the things I wanted. I found some of the code on this forum. I also noticed the event handler needs to be attached after a call to Show method. If it is attached prior, it doesn't work. I guess DockingManager integrates the form right before it is shown (I see MdiChildActivate event on the Form class, maybe you used that?).

The code in the base mdi child form looks like this:
Private Sub frmMdiChildBase_FormClosed(ByVal sender As ObjectByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed 
    ' when form is closed - try to find document pane and close it 
    Dim docPane As DocumentPane = GetParent(Of DocumentPane)(Me
    If docPane IsNot Nothing Then 
        docPane.DockManager.Remove(docPane) 
    End If 
End Sub 
 
Public Shared Function GetParent(Of TargetType As {Control})(ByVal c As Control) As TargetType 
    While c.Parent IsNot Nothing 
        If TypeOf c.Parent Is TargetType Then 
            Return c.Parent 
        End If 
        c = c.Parent 
    End While 
    Return Nothing 
End Function 

I understand you probably had other more important stuff to implement. This simply had to wait it's turn in some future release...
0
Julian Benkov
Telerik team
answered on 23 May 2008, 07:31 AM
Hi Dragoljub,

Thank you for the feedback and code snippets. You are absolutely right for the integration of DockingManager. We will change this behavior to be independent from the Show method and the order of API calls.

Currently, you may continue to use your approach for this scenario.

All the best,
Julian Benkov
the Telerik team

Instantly find answers to your questions at the new Telerik Support Center
0
Garrison
Top achievements
Rank 1
answered on 21 Mar 2009, 11:39 AM
Any update on this issue?  It appears to still be an issue with RadControls for WinForms Q3 2008 SP2 (8.2.0). 

UPDATE: This issue still exists in the 2009.1 3/11 release. 
0
Julian Benkov
Telerik team
answered on 24 Mar 2009, 04:43 PM
Hello Garrison,

For this and other issues related to the docking layout and windows forms management, we are currently implementing absolutely new RadDock component.

Please refer to this blog post for additional information. The new RadDock will be available in Q2 2009 release.

Sincerely yours,
Julian Benkov
the Telerik team

Check out Telerik Trainer , the state of the art learning tool for Telerik products.
0
Garrison
Top achievements
Rank 1
answered on 26 Aug 2009, 12:05 PM
FYI, similar problems continue to occur with the Q2 2009 SP1 (2009.2.9.729) release of the RadDock component.
For example, the FormClosing event does not fire for MDI child RadForms.
0
Georgi
Telerik team
answered on 27 Aug 2009, 01:25 PM
Hello Garrison,

Thank you for contacting us.

I have tested thoroughly the sequence of events with an MDI Child Form, parented by our RadDock as a TabbedDocument, and I did not find any improper behavior.

Could you please be more specific what actually is not working as expected with the Form.Closing and Form.Closed events? A very simple application which demonstrates the problem would be most helpful. Feel free to open a new support ticket in order to send us the app.

Thank you for your time.
 

Greetings,
Georgi
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Garrison
Top achievements
Rank 1
answered on 01 Sep 2009, 02:51 PM
From the original post, item 2 still appears to be unresolved in the latest build.
Item 2: When I click the document pane's X button it disappears, but the FormClosing/FormClosed events do not fire.

I've created a small example project and have attached it to a support ticket for your review.

Thanks,
-Garrison
0
Georgi
Telerik team
answered on 04 Sep 2009, 08:29 AM
Hello Garrison,

I answered your support ticket but since it may be interesting for other people I will post it here also:


Thank you for the sample project. The problem here is that a document window by default will have close action CloseAndDispose. When a Close request occurs, RadDock will close the window and explicitly dispose it (using DockWindow.Dispose). This dispose request on its hand will internally call Form.Dispose and thus skipping the first two events - Closing and Closed. For Q3 2009 we will add support for calling these two events for child Forms so that our users will be able to hook the Closing event and optionally cancel it.

Currently you may do a simple workaround that will associate a DockWindowClosing event with Form.Closing one:

void radDock1_DockWindowClosing(object sender, DockWindowCancelEventArgs e) 
    if (e.DockWindow.DockState == DockState.TabbedDocument && 
        e.DockWindow.Controls.Count > 0) 
    { 
        Form child = e.DockWindow.Controls[0] as Form; 
        child.Close(); 
        e.Cancel = !child.IsDisposed; 
    } 


Sincerely yours,
Georgi
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
F5F5F5
Top achievements
Rank 1
answered on 22 Oct 2009, 11:37 AM

I believe have a solution to this problem that requires no changes to the MDI child forms, by subclassing the RadDock control and using reflection to call the OnFormClosing and OnFormClosed events in the form. Then use the RadDockManager control on your form instead of the RadDockControl.

using System.Windows.Forms;  
using Telerik.WinControls.UI.Docking;  
using System.Reflection;  
 
namespace TelerikTest  
{  
    public class RadDockManager : Telerik.WinControls.UI.Docking.RadDock  
    {  
 
        const string onFormClosing = "OnFormClosing";  
        const string onFormClosed = "OnFormClosed";  
 
        private MethodInfo _formClosingMethod;
        private MethodInfo FormClosingMethod  
        {  
            get 
            {  
                if (_formClosingMethod == null)  
                    _formClosingMethod = typeof(Form).GetMethod(onFormClosing, BindingFlags.Instance | BindingFlags.NonPublic);  
                return _formClosingMethod;  
            }  
        }  
 
        private MethodInfo _formClosedMethod;  
        private MethodInfo FormClosedMethod  
        {  
            get 
            {  
                if (_formClosedMethod == null)  
                    _formClosedMethod = typeof(Form).GetMethod(onFormClosed, BindingFlags.Instance | BindingFlags.NonPublic);  
                return _formClosedMethod;  
            }  
        }  
 
 
        protected override void OnDockWindowClosing(Telerik.WinControls.UI.Docking.DockWindowCancelEventArgs e)  
        {  
            Form f = e.DockWindow.GetHostedForm();  
 
            if (f == null || f.Disposing || f.IsDisposed) return;  
 
            FormClosingEventArgs fce = new FormClosingEventArgs(CloseReason.UserClosing, e.Cancel);  
            FormClosingMethod.Invoke(f, new object[] { fce });  
            e.Cancel = fce.Cancel;  
 
            if (e.Cancel) return;  
            base.OnDockWindowClosing(e);  
 
            if (e.Cancel) return;  
            FormClosedMethod.Invoke(f, new object[] { new FormClosedEventArgs(CloseReason.UserClosing) });  
 
        }  
 
        protected override void OnDockWindowAdded(DockWindowEventArgs e)  
        {  
            base.OnDockWindowAdded(e);  
 
            Form f = e.DockWindow.GetHostedForm();  
            if (f == nullreturn;  
 
            // Must use Closing event - not FormClosing event.  
            f.Closing += new System.ComponentModel.CancelEventHandler(Form_Closing);  
        }  
 
        void Form_Closing(object sender, System.ComponentModel.CancelEventArgs e)  
        {  
            Form form = sender as Form;  
            if (form == nullreturn;  
 
            DockWindow dw = GetHostWindow(form);  
            if (dw == nullreturn;  
 
            e.Cancel = true;  
            this.RemoveWindow(dw, DockWindowCloseAction.CloseAndDispose);  
        }  
   }  
 
    public static class RadDockExtensions  
    {  
        public static Form GetHostedForm(this DockWindow dockWindow)  
        {  
            HostWindow hw = dockWindow as HostWindow;  
            return hw == nullnull : hw.Content as Form;  
        }  
    }  
0
Vassil Petev
Telerik team
answered on 22 Oct 2009, 12:18 PM
Thank you for sharing your solution with the community, Alan, we have updated your Telerik points.


Best wishes,
Vassil
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Per
Top achievements
Rank 1
answered on 25 Jan 2010, 09:10 AM
Hi!

Now that the Q3 has been released, whats the easiest way to stop a MDI form from clsoing then the user clicks on the X button?

At the moment im using this code:
  Private Sub RadDock1_DockWindowClosing(ByVal sender As ObjectByVal e As Telerik.WinControls.UI.Docking.DockWindowCancelEventArgs) Handles RadDock1.DockWindowClosing  
    If RadDock1.MdiChildren.Length <= 1 Then e.Cancel = True 
  End Sub 
But it's not working.

It stops the tab from closing but the MDI form is still disposed :(

Regards
Per
0
Nikolay
Telerik team
answered on 27 Jan 2010, 01:11 PM
Hi Per,

Due to numerous clients' requests, we have changed the RadDock behavior and when you close a DockWindow hosting a Form, we internally call Form.Close method upon DockWindowClosing notification. If the Close request is not canceled, then RadDock will proceed with the CloseWindow request, otherwise it will be canceled also. This routine however is called BEFORE the RadDock.DockWindowClosing event is triggered. If the Form is successfully closed (in the same time it is cleared as a reference and the Content property of the Hosting Window is null), the RadDock.DockWindowClosing is called, and if not canceled RadDock.DockWindowClosed is raised. Here is a quick summary of events order:

Form.Closing
Form.Closed
RadDock.DockWindowClosing
RadDock.DockWindowClosed

In short, in order to prevent the user from closing a DockWindow containing a form, just cancel the FormClosing event:

void mdiChildForm_FormClosing(object sender, FormClosingEventArgs e)
{
    e.Cancel = true;
}

If you have additional questions, feel free to contact me.

Greetings,

Nikolay
the Telerik team

 


Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
Tags
Dock
Asked by
Dragoljub
Top achievements
Rank 1
Answers by
Julian Benkov
Telerik team
Dragoljub
Top achievements
Rank 1
Garrison
Top achievements
Rank 1
Georgi
Telerik team
F5F5F5
Top achievements
Rank 1
Vassil Petev
Telerik team
Per
Top achievements
Rank 1
Nikolay
Telerik team
Share this question
or