Closing an MDI Child Form

14 posts, 0 answers
  1. Dragoljub
    Dragoljub avatar
    26 posts
    Member since:
    Feb 2008

    Posted 22 May 2008 Link to this post

    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?
  2. Julian Benkov
    Admin
    Julian Benkov avatar
    1135 posts

    Posted 22 May 2008 Link to this post

    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
  3. UI for WinForms is Visual Studio 2017 Ready
  4. Dragoljub
    Dragoljub avatar
    26 posts
    Member since:
    Feb 2008

    Posted 22 May 2008 Link to this post

    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...
  5. Julian Benkov
    Admin
    Julian Benkov avatar
    1135 posts

    Posted 23 May 2008 Link to this post

    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
  6. Garrison
    Garrison avatar
    10 posts
    Member since:
    Apr 2008

    Posted 21 Mar 2009 Link to this post

    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. 
  7. Julian Benkov
    Admin
    Julian Benkov avatar
    1135 posts

    Posted 24 Mar 2009 Link to this post

    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.
  8. Garrison
    Garrison avatar
    10 posts
    Member since:
    Apr 2008

    Posted 26 Aug 2009 Link to this post

    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.
  9. Georgi
    Admin
    Georgi avatar
    296 posts

    Posted 27 Aug 2009 Link to this post

    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.
  10. Garrison
    Garrison avatar
    10 posts
    Member since:
    Apr 2008

    Posted 01 Sep 2009 Link to this post

    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
  11. Georgi
    Admin
    Georgi avatar
    296 posts

    Posted 04 Sep 2009 Link to this post

    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.
  12. F5F5F5
    F5F5F5 avatar
    7 posts
    Member since:
    Oct 2009

    Posted 22 Oct 2009 Link to this post

    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;  
            }  
        }  
  13. Vassil Petev
    Admin
    Vassil Petev avatar
    1765 posts

    Posted 22 Oct 2009 Link to this post

    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.
  14. Per
    Per avatar
    116 posts
    Member since:
    Jan 2008

    Posted 25 Jan 2010 Link to this post

    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
  15. Nikolay
    Admin
    Nikolay avatar
    1804 posts

    Posted 27 Jan 2010 Link to this post

    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.
Back to Top
UI for WinForms is Visual Studio 2017 Ready