DgnPlatformNet |
This article is for C# developers who want to write an application for
MicroStation CONNECT.
It describes a way to use a .NET Form
in your own app.
This is not a complete application: rather, it describes what might otherwise be a non-intuitive approach to solve a problem.
This article introduces a .NET Form
class TopLevelForm
.
TopLevelForm
is intended to be inherited by your Form
.
Desirable Form
behaviour implemented by the TopLevelForm
class includes …
Form
to MicroStation
Form
after it's been minimized
Many AddIns have a top-level form or dialog box.
The form opens when the AddIn is loaded (mdl load MyApp
).
This screenshot is taken from our File Collector example …
A user can minimize a form (using the - button) or dismiss the form (using the x button).
Once minimized or dismissed, there's no way to restore the form to make it visible.
A related problem is that a .NET AddIn cannot be unloaded from MicroStation.
Consequently, you can't key-in mdl unload MyApp
followed by mdl load MyApp
to pop that dialog.
When you deliver your AddIn to a customer, you want it to look and behave like any other MicroStation dialog-based app.
You do that by inheriting your Form
from
Bentley.MstnPlatformNET.WinForms.Adapter
.
Then, in code, you attach your Form
to MicroStation.
However, Bentley.MstnPlatformNET.WinForms.Adapter
is not compatible with the Visual Studio designer.
When you attempt to open such a class, Visual Studio complains …
To get around that problem, during development you should inherit your dialog from Form
and switch to the Bentley class for your release build.
A simple way to achieve that result is to define a symbol in your DEBUG build, and use that to determine your form's class …
#if DESIGN public partial class TopLevelForm : Form #else public partial class TopLevelForm : Bentley.MstnPlatformNET.WinForms.Adapter #endif
Here's where you define that macro in your Visual Studio DEBUG configuration …
Thanks to Maury for that tip!
You switch between Debug, where DESIGN
is defined, and Release using the Viz Studio Configuration selector.
The TopLevelForm
class described here includes that pattern.
The base class described here is named TopLevelForm
. Write your own class to inherit from that class …
public class MyForm : TopLevelForm {}
TopLevelForm
uses the configuration switch above to derive from the appropriate form, so you don't have to.
When you attach a Form to MicroStation, it automatically gains certain behaviour.
The MstnPlatformNET API provides several AttachXxx
methods.
For our TopLevelForm
we use the AttachAsTopLevelForm()
method …
const bool UseMicroStationPositioning = true; AttachAsTopLevelForm(addIn, UseMicroStationPositioning);
The addIn
parameter is the run-time instance of your AddIn.
Here's an example of MyForm
's constructor that calls its base class TopLevelForm
…
public MyForm() : base (MyApp.Instance)
Where MyApp.Instance
is a static method of your AddIn.
It's a pattern that is common to the .NET examples provided with the MicroStation CONNECT SDK.
When a user closes your Form
using the x button, the form is destroyed.
If your AddIn maintains a reference to the form, then it should be set to null
.
The OnClosed event handler provides the hook for you to achieve that result.
We start by defining a delegate method …
public delegate void FormClosed();
That delegate is assigned to a member of the TopLevelForm
class …
FormClosed _FormClosedDelegate;
The delegate is called when the form is closed …
private void TopLevelForm_FormClosed(object sender, FormClosedEventArgs e) { _FormClosedDelegate(); }
That calls the FormClosed()
method in your AddIn …
public void FormClosed() { _form = null; }
The we create an instance of our AddIn's form, we pass a reference to the AddIn's FormClosed()
method.
That reference is stored in the _FormClosedDelegate
mentioned previously.
public MyForm CreateForm() { if (null == _form) { _form = new MyForm(Instance.FormClosed); _form.Show(); } return _form; }
When a Form
is mimimized, it's visually shrunk.
The Form
still exists, the the _form
reference in your AddIn remains valid.
The TopLevelForm.Restore()
method takes care of popping your Form
.
However, the method implementation difference depending on its base class …
Form
: implements Restore()
Bentley.MstnPlatformNET.WinForms.Adapter
: uses the Restore()
method provided by that class
Here's the implementation of Restore()
…
public void Restore() { if (WindowState.HasFlag(System.Windows.Forms.FormWindowState.Minimized)) { WindowState = System.Windows.Forms.FormWindowState.Normal; } }
This article was written as a summary of my own experience in developing a .NET Form
for MicroStation.
I was helped on my way by hints & tips on the
MicroStation Programming Forum.
Special thanks go to …
Form
The code and usage example for the TopLevelForm
class is provided with the
DGN File Enumerator
project.
Post questions about MicroStation programming to the MicroStation Programming Forum.