MicroStation .NET: Scan for Tag Elements

  • Products
  • Services
  • All Publications
  • CONNECT Publications
  • Links
  • WishList
  • LA Solutions
  • Home
LA Solutions
tel: +44 1398 361 800
DgnPlatformNet

Introduction

This article is for C# developers who want to write an AddIn for MicroStation CONNECT. It is an introduction to the coding required to acquire tag elements in a DGN model by scanning. We show two approaches that obtain similar results …

  1. by implementating a scan filter that looks explicitly for TagElements
  2. by collecting instances of TagElements that have an association relationship with their host element
Tag Scanner Dialog

This is a complete, working example with C# source code. You can download the Visual Studio project.

Be Communities

If you want to ask questions about C# development for MicroStation CONNECT, post your question to the MicroStation Programming Forum.

Model Scanning

A DGN model is a container. It contains graphic elements, such as lines, arcs and shapes. If you want your code to do anything with MicroStation elements, you must understand ways to obtain those elements.

If you want to read an introduction to harvesting elements from a DGN model, take a look at our previous articles about element enumeration and scanning using the DgnPlatformNet API …

  1. Model Scanning and Enumeration introduction
  2. Model Scanning intermediate coverage of scanning

Tag Scanning

This article offers a more advanced example of scanning. In this example, we want to find elements (termed 'host elements' here) annotated with MicroStation TagElements. When we find those host elements we present a list in a Windows Form that is part of the example application.

Legacy Scanning

The project's Scanner class implements a traditional idiom to obtain host elements. We scan a DGN model for certain element types (MSElementType.Tag), and for each TagElement find its host element. The host element is stored in a dictionary keyed by its ElementId. That way, we don't store any duplicates.

EC Scanning

The purpose of this approach is to show how we can use ECSchema relationships. A TagElement has an association relationship with its host. We exploit classes that support ECSchemas DgnElementSchema and DgnContentRelationshipSchema. Both schemas are delivered with MicroStation.

In this example, the scanner is instructed to obtain any graphical element that isn't a MSElementType.Tag. For each candidate element found by the scanner, we check to see if a TagElement is associated with it. If we find that association, we add the host to our list of found elements.

EC Relationship

Here's the code that set up the relationship test for each candidate element. It may not be clear what all this means — the DgnPlatformNet documentation could be more helpful …

//  Add Visual Studio project references to these assemblies
using Bentley.DgnPlatformNET.DgnEC;
using Bentley.DgnPlatformNET.Elements;
using Bentley.DgnPlatformNET;
using Bentley.MstnPlatformNET;
using ECI = Bentley.ECObjects.Instance;
using ECS = Bentley.ECObjects.Schema;       //  Bentley.ECObjects3.dll
using ECQ = Bentley.EC.Persistence.Query;   //  Bentley.EC.Persistence3.dll
//  Set the EC scope to find graphic elements
FindInstancesScopeOption opts = new FindInstancesScopeOption(DgnECHostType.Element);
opts.ExposesHidden = true;
FindInstancesScope.CreateScope(host, opts);
//  Read the ECSchemas delivered with MicroStation
var file = session.GetActiveDgnFile();
var mgr = DgnECManager.Manager;
var elemSchema = mgr.LocateDeliveredSchema("DgnElementSchema", 1, 0, ECS.SchemaMatchType.LatestCompatible, file);
var relSchema = mgr.LocateDeliveredSchema("DgnContentRelationshipSchema", 1, 0, ECS.SchemaMatchType.LatestCompatible, file);
//  Create an ECQuery for graphical DGN elements
var query = new ECQ.ECQuery(new ECQ.SearchClass(elemSchema["GraphicalElement"], true));
//  Create a ECRelationship for an element associated with a TagElement
var relSpec = new ECQ.QueryRelatedClassSpecifier(relSchema["AssociativeElementRelationship"]
  as ECS.IECRelationshipClass,
  true,
  ECI.RelatedInstanceDirection.Backward, elemSchema["TagElement"], true);
//  Add the ECRelationship clause to the ECQuery
query.SelectClause.SelectedRelatedInstances.Add(new ECQ.RelatedInstanceSelectCriteria(relSpec, true));
//  Invoke the query to find EC instances on the host DGN element
using (DgnECInstanceCollection instances = mgr.FindInstances(FindInstancesScope.CreateScope(host, opts), query))
{
  ... do something with DgnECInstanceCollection
}
//  Evaluate each EC instance
foreach (var instance in instances)
{
    DgnECRelationshipCollection ecRelationshipInstanceCollection =
        (DgnECRelationshipCollection)instance.GetRelationshipInstances();
    foreach (var relationship in ecRelationshipInstanceCollection)
    {
        var tagInstance = relationship.Source as IDgnECInstance;
        TagElement tag = (TagElement)tagInstance.Element;
        if (0 == String.Compare(setName, tag.TagSetName, true))
        {
            StringBuilder s = new StringBuilder();
            s.AppendFormat("Tag Element: {0} '{1}' '{2}'", tag.ElementId, tag.TagName, tag.GetTagValue().ToString());
            TagScanner.ShowMessage(s);
            ++nTags;
        }
    }
}

Scanner Dialog

The dialog shown above has an option button that displays a list of tag sets defined in the active DGN model. That button shows tag set example …

Scan for tag set example

The screenshot above shows the result of scanning for elements that host tag set example. The ListView control shows a list of element IDs (the ID of each host) and the host's element type. The technique for acquiring that list is described above.

We use the Dictionary populated by the scanner as the data source for the ListView control

Dialog Controls

The dialog has two controls that provide feedback to the user …

  1. When user selects a row in the ListView control, the corresponding element in the DGN model is highlighted. Read this article about element highlighting to see how that's done.
  2. When user clicks the Zoom button, we adjust a MicroStation view to focus on the element represented by the selected row in the ListView control. Read this article about focussing on an element.
Highlight Selected Element

There are classes that implement these techniques in the downloadable project.

Namespaces

MicroStation .NET code lives in the Bentley namespace, or a namespace within the scope of Bentley. In this example we're using classes and methods in the Bentley.DgnPlatformNET and Bentley.DgnPlatformNET.Elements namespaces. Put the following using statements in any C# code module that uses a class in those namespaces …

using Bentley.DgnPlatformNET;
using Bentley.DgnPlatformNET.Elements;

Model Scanning

You can read more about the mechanics of scanning a model elsewhere …

Overview of scanning Model Scanning
Setting your scan criteria Scan Criteria
Writing a scan delegate (callback function) Scan Delegate Method
Element Type Test Setting the type test bit-mask

Element Type Test

In the legacy scanning example, we're looking specifically for tag elements. We set the scan criteria like this …

ScanCriteria criteria = new ScanCriteria();
criteria.SetDrawnElements();
criteria.SetModelRef(model_);
//  We're interested only in tag elements
MSElementType[] types = new MSElementType[1];
types[0] = MSElementType.Tag;
criteria.AddElementTypes(types);

Finding Tag Host Elements

For each TagElement that our scan discovers, we want its parent or host element. From a user perspective, that's the element to which the tag is attached. We're interested in only those tags that belong to a named tag set. In our scan delegate function, we need to perform these tasks …

  • Check that we've been given a tag element
  • Determine if the tag is a member of the named tag set
  • If the tag matches …
    • Get its host element
    • Add that element to our Dictionary of elements. The key used in the Dictionary is the unique Element ID

The Dictionary is a list of Elements keyed by element ID …

Dictionary <ElementId, Element>  hosts_;

Here's the code in the scan delegate that implements those requirements …

if (MSElementType.Tag == el.ElementType)
{
    ++nTags_;
    TagElement tag = (TagElement)el;
    if (0 == string.Compare(tag.TagSetName, tagSetName_, true))
    {
      Element host = tag.GetTargetElement();
      if (!hosts_.ContainsKey(host.ElementId))
        hosts_.Add(host.ElementId,host);
    }
}

The result of the tag scan is a Dictionary of host elements (not tag elements), keyed by the host's ID. That list is added to the dialog's ListView control …

Scan for tag set example

Commands

This MicroStation AddIn has a small command table, in file Commands.xml. The command handlers are in class KeyinCommands. You can key-in the commands below in MicroStation's key-in dialog. Commands are not case-sensitive …

Scanner Command Table
Command Option Comment
TAGSCANNER SCAN Scan for TagElements
TAGSCANNER ECSCAN Scan for anything but a TagElement, then find the associated TagElement

After keying-in the above command, observe MicroStation's Message Center. Make sure that the debug option is enabled (right-click in the Message Center to see its options). You will see a list of the element IDs and types discovered. That list is presented in the Tag Scanner dialog above.


Download

Download the Tag Scanner Project

You can download the Tag Scanner Project Visual Studio project. The project was built using Visual Studio 2013 and .NET Framework 4.5 as required by MicroStation CONNECT prior to Update 5. It should work with MicroStation CONNECT Update 5 and later but has not been tested.

The project is complete: it includes all source code, the command table XML file, the Visual Studio solution file and is set up to build a DLL. The DLL is placed in your ..\MicroStation\mdlapps folder. It's similar, in that respect, to the .NET examples delivered with the MicroStation CONNECT SDK.

Build the project, which will place file TagScanner.DLL in your ..\MicroStation\mdlapps folder. Start MicroStation and open the key-in window (from the Utilities ribbon group). Key-in
mdl load TagScanner
You should see a message confirming that the application is loaded. The Tag Scanner dialog will pop.

Questions

Post questions about MicroStation programming to the MicroStation Programming Forum.


Bentley Technology Partner

Trademarks

All trademarks are acknowledged. Trademarks may be registered in some jurisdictions.
e-mail Contact LA Solutions using this enquiry form.

Home
Home
Updated on 28-Dec-21 Copyright © 2016…2025 Jon Summers