Chapter 7: Responding to MicroStation Events


In this chapter, we'll explore how MicroStation events work and how they can help your applications respond automatically to changes made by users. 

The table below introduces some of the most used event types and their corresponding event handlers. 

 

Event Type

Event Handler

Reference design file

ReferenceAttachedEvent method

Uninstall reference files

ReferenceDetachedEvent method

Open or close the design file

NewDesignFileEvent (attached to NewDesignFileEvent)

Save As command

FileSaveAsEvent method

Activation model

ModelChangedEvent method

Tracking element changes

ElementChangedEvent methods

Selection set changes

SelectionChangedEvent method

Level changes

LevelChangeEvent method

Select different views

SelectedViewChangedEvent method

Uninstall program

UnloadAnyAppEvent method

 

To make these concepts easier to understand, we'll build a simple example using ILevelChangeEvents and NewDesignFileEventHandler.

 

This example displays all levels from the active DGN file in a dialog box. As you work in the Level Manager, any changes you make, such as adding, deleting, or renaming, level changes are automatically reflected in the dialog. This keeps the displayed information up to date without requiring a manual refresh.

The application also responds when a different DGN file is opened. Whenever a new design file becomes active, the dialog automatically refreshes and displays the levels from the newly opened DGN file.

By the end of this chapter, you'll understand how to listen for MicroStation events and use them to keep your application's user interface synchronized with the current design file.

 

Let's build this feature step by step.

 

  1. Create a Form LevelChangedForm

Add a List box control to the Form. The form design should resemble the figure shown below.

 

 

Form (Name) = LevelChangedForm / FormBorderStyle = FixedDialog / MaximizeBox = False / MinimumBox = False
/ ShowIcon = False / Size = 288,423 / Text = LevelChangedForm
ListBox (Name) = listBox1 / Location = 5,13 / Modifiers = Public / Size = 272,372 / Sorted = True

 

  1. Update LevelChangedForm.cs

 

Open LevelChangedForm.cs in code mode and modify its content. Here are a few things to note:

 

using Bentley.DgnPlatformNET;
using Bentley.MstnPlatformNET;
using Bentley.MstnPlatformNET.WinForms;
using Bentley.UI.Controls.WinForms.TelerikWindowsForms;
using csAddins7;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static Bentley.MstnPlatformNET.AddIn;

namespace csAddins7
{
    public partial class LevelChangedForm : //Form
        Adapter
    {
        public LevelChangedForm()
        {
            InitializeComponent();
            MyAddin.Addin.LevelChangeEvent += LevelChangeEventHandler;
            MyAddin.Addin.NewDesignFileEvent += NewDesignFileEventHandler;
            PopulateLevelList();
        }

        private void LevelChangedForm_Load(object sender, EventArgs e)
        {
            FileLevelCache fileLevelCache = Session.Instance.GetActiveDgnFile().GetLevelCache();
            LevelHandleCollection levelHandleCol = fileLevelCache.GetHandles();
            foreach (LevelHandle levelHandle in levelHandleCol)
            {
                listBox1.Items.Add(levelHandle.Name);
            }
        }

        private void LevelChangedForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            MyAddin.Addin.LevelChangeEvent -= LevelChangeEventHandler;
            MyAddin.Addin.NewDesignFileEvent -= NewDesignFileEventHandler;
        }

        private void LevelChangeEventHandler(AddIn senderIn, LevelChangeEventArgs eventArgsIn)
        {
            if (eventArgsIn.Change == LevelChangeEventArgs.ChangeType.Create ||
                eventArgsIn.Change == LevelChangeEventArgs.ChangeType.Delete ||
                eventArgsIn.Change == LevelChangeEventArgs.ChangeType.TableRewrite ||
                eventArgsIn.Change == LevelChangeEventArgs.ChangeType.ChangeName)
                PopulateLevelList();
        }

        private void NewDesignFileEventHandler(AddIn sender, NewDesignFileEventArgs eventArgs)
        {
            if (AddIn.NewDesignFileEventArgs.When.AfterDesignFileOpen == eventArgs.WhenCode)
                PopulateLevelList();
        }

        private void PopulateLevelList()
        {
            listBox1.Items.Clear();
            LevelHandleCollection levelCollection = Session.Instance.GetActiveDgnFile()
                                                          .GetLevelCache().GetHandles();
            foreach (LevelHandle myLvl in levelCollection)
                listBox1.Items.Add(myLvl.Name);
        }
    }
}

 

  1. Update commands.xml

 

Open the commands.xml file, add the command csAddins7 DemoForm LevelChanged, and specify its processing function as csAddins7.DemoForm.LevelChanged.

 

  1. Update DemoForm.cs

 

Open DemoForm.cs, turn to the end of the code and add the command processing function LevelChanged as follows. This code opens the LevelChangedForm in Singleton mode, which guarantees that only one form can be opened at the same time. 

 

        private static LevelChangedForm myLevelForm = null;

        public static void LevelChanged(string unparsed)
        {
            if (null == myLevelForm || myLevelForm.IsDisposed)
            {
                myLevelForm = new LevelChangedForm();
                myLevelForm.AttachAsTopLevelForm(MyAddin.Addin, false);
                myLevelForm.Show();
            }
            else
                myLevelForm.Activate();
        }

 

  1. Build Solution

 

Under menus, select Build > Build Solution to compile the solution.

 

Open MicroStation's Level Manager, as shown in the figure below. When you add, delete or rename a Level in the Level Manager dialog, the display in our LevelChanged form will also be updated immediately. You can also test further by opening another DGN, and you will find that the content in the LevelChanged form will change, displaying the levels from the new DGN file.

 

 

You can download the source code for this wiki here.  

 

Prev: Use DgnPrimitiveTool and DgnElementSetTool Next: Calling C/C++ Functions in Add-ins