Showing and Closing Modeless Form Dialog Box With System Windows Forms Form

Showing and Closing Modeless Form Dialog Box With System Windows Forms Form


When programming AutoCAD, there are 2 styles of dialog box can be shown: Modal Dialog Box and Modeless Dialog Box. Modal dialog box is usually used for collecting user inputs, while modeless dialog box is more focused on showing information. While the dialog box displayed, modal dialog box blocks user from direct interaction with AutoCAD (that is, user cannot interact with AutoCAD UI until the modal dialog box is dismissed. But it DOES NOT mean AutoCAD stops its processing until the modal dialog box is closed), modeless dialog box floats on top AutoCAD UI and user can still interact with AutoCAD UI.

With AutoCAD .NET API, one can use either Windows Form or WPF Window as dialog box. This discussion is limited to Windows Form, because it is still used far more often than WPF window.

System.Windows.Forms.Form class has 2 methods to show a form: ShowDialog() and Show(). The former shows a form as modal form and the latter shows a form as modeless form. Depending on which method is used to show a form, the forms closing behaviour is different (either by calling Form.Close(), or by clicking "x" button on the form), which I have seen is misunderstood quite often.

The difference is:
  • For modeless form, Form.Close() (or clicking the "x" button on the form. Ill not repeat this hereafter) also calls the Dispose() method;
  • For modal form, Form.Close() only hide the form, which is basically equivalent to setting the forms Visible property to False. The modal form can also be "closed" by calling Form.Hide(), by setting Form.DialogResult. That is, the modal form cannot be really closed unless Form.Dispose() is called explicitly.
In AutoCAD .NET API, one should use ShowModalDialog()/ShowModelessDialog() instead of Form.ShowDialog/Form.Show() to display modal/modeless dialog boxes. These 2 methods have the same behaviours in terms of how form/dialog box is closed.

When using modeless form in AutoCAD, one thing to be careful is how the form is opened and closed/hidden. The fact while the form is open AutoCADs active document can be changed by user interaction makes things a bit complicated, if the information showing on the form is document specific. Here I am going to show some code dealing with modeless form in 2 different ways: creating a singleton form in entire AutoCAD session; or creating multiple forms (per document) and showing them accordingly.

Here is the Visual Studio 2012 solution, which includes 3 projects:





Project "DwgDataView" contains a Windows UserControl and Windows Form that can be used in AutoCAD addins:




This project also has a data model class and a AutoCAD utility class to get and hold drawing specific information.

The code follows.

Class DrawingData:

    1 namespace DwgDataView
    2 {
    3     public class DrawingData
    4     {
    5         public string CurrentDocName { set; get; }
    6         public string CurrentLayer { set; get; }
    7         public double CurrentDimScale { set; get; }
    8     }
    9 }

Class DrawingDataUtil:

    1 using System;
    2 using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
    3 
    4 namespace DwgDataView
    5 {
    6     public class DrawingDataUtil
    7     {
    8         public static DrawingData GetCurrentDrawingData()
    9         {
   10             return new DrawingData
   11             {
   12                 CurrentDocName=AcadApp.DocumentManager.MdiActiveDocument.Name,
   13                 CurrentLayer=AcadApp.GetSystemVariable("CLAYER").ToString(),
   14                 CurrentDimScale=Convert.ToDouble(AcadApp.GetSystemVariable("DIMSCALE"))
   15             };
   16         }
   17     }
   18 }

Code of UserControl DrawingDataView:

    1 using System.Windows.Forms;
    2 
    3 namespace DwgDataView
    4 {
    5     public partial class DrawingDataView : UserControl
    6     {
    7         public DrawingDataView()
    8         {
    9             InitializeComponent();
   10         }
   11 
   12         public void SetDataView(DrawingData data)
   13         {
   14             txtDrawingName.Text = data.CurrentDocName;
   15             txtLayer.Text = data.CurrentLayer;
   16             txtDimScale.Text = data.CurrentDimScale.ToString();
   17         }
   18 
   19         public void ClearDataView()
   20         {
   21             txtDimScale.Text = "";
   22             txtDrawingName.Text = "";
   23             txtLayer.Text = "";
   24         }
   25     }
   26 }

Code of Form frmDrawing:

    1 using System;
    2 using System.Windows.Forms;
    3 
    4 namespace DwgDataView
    5 {
    6     public partial class frmDrawing : Form
    7     {
    8         //This property is only used for showing multiple modeless forms
    9         public bool ShowMe { set; get; }
   10 
   11         //This property is used to make the modeless form close differently:
   12         //hidden as closed, or disposed as closed
   13         public bool HiddenAsClosed { set; get; }
   14 
   15         public frmDrawing()
   16         {
   17             InitializeComponent();
   18 
   19             ShowMe = false;
   20             HiddenAsClosed = true;
   21         }
   22 
   23         public void SetDataView(DrawingData data)
   24         {
   25             ctlDataView.SetDataView(data);
   26         }
   27 
   28         public void ClearDataView()
   29         {
   30             ctlDataView.ClearDataView();
   31         }
   32 
   33         private void btnClose_Click(object sender, EventArgs e)
   34         {
   35             if (HiddenAsClosed)
   36             {
   37                 ShowMe = false;
   38                 this.Hide();
   39             }
   40             else
   41             {
   42                 this.Close();
   43             }
   44         }
   45 
   46         private void frmDrawing_FormClosing(object sender, FormClosingEventArgs e)
   47         {
   48             if (HiddenAsClosed)
   49             {
   50                 e.Cancel = true;
   51                 ShowMe = false;
   52                 this.Hide();
   53             }
   54         }
   55     }
   56 }

In the project SigletonModelessDialog, the modeless form will not be disposed (by calling Form.Dispose() or Form.Close()) once it is instantiated. Users interaction with the form can hide the form.

In this scenario, when the modeless form deals with per document data, we need to make sure the modeless form is tied to correct document, usually the active document, which can change when user works with AutoCAD while the modeless form is visible.

Here is code of project SingletonModelessDialog:

    1 using Autodesk.AutoCAD.ApplicationServices;
    2 using Autodesk.AutoCAD.EditorInput;
    3 using Autodesk.AutoCAD.Runtime;
    4 using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
    5 
    6 using DwgDataView;
    7 
    8 [assembly: CommandClass(typeof(SingletonModelessDialog.MyCommands))]
    9 [assembly: ExtensionApplication(typeof(SingletonModelessDialog.MyCommands))]
   10 
   11 namespace SingletonModelessDialog
   12 {
   13     public class MyCommands : IExtensionApplication
   14     {
   15         private static frmDrawing _frm = null;
   16 
   17         public void Initialize()
   18         {
   19             DocumentCollection dwgCol = AcadApp.DocumentManager;
   20             dwgCol.DocumentBecameCurrent += dwgCol_DocumentBecameCurrent;
   21             Document dwg = AcadApp.DocumentManager.MdiActiveDocument;
   22             Editor ed = dwg.Editor;
   23 
   24             try
   25             {
   26                 ed.WriteMessage(" Initializing {0}...", this.GetType().Name);
   27 
   28                 ed.WriteMessage("comleted ");
   29             }
   30             catch (System.Exception ex)
   31             {
   32                 ed.WriteMessage("failed: {0}", ex.ToString());
   33             }
   34         }
   35 
   36         public void Terminate()
   37         {
   38             if (_frm != null)
   39             {
   40                 if (!_frm.IsDisposed) _frm.Dispose();
   41             }
   42         }
   43 
   44         private void dwgCol_DocumentBecameCurrent(
   45             object sender, DocumentCollectionEventArgs e)
   46         {
   47             if (_frm == null) return;


visit link download

Popular posts from this blog

SolidWorks 2017 Premium Full Crack

Game School Minecraft

Resident Evil Revelations Raid Mode Custom Parts