[MSCE v17 C#] Detect missing linestyle

I'm writing an COM based C# where I'm going thru all the elements in a model and trying to determine if the element's custom linestyle has been found or is missing.

Attached is simple code snippet to run thru the graphical elements and read linestyle (this is basic with no error checking/handling yet).

        public static void GetLineType(string unparsed)
        {
            BIM.ElementScanCriteria elementScanCriteria = new BIM.ElementScanCriteriaClass();
            elementScanCriteria.IncludeOnlyVisible();

            BIM.ElementEnumerator elementEnumerator = Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp.ActiveModelReference.Scan(elementScanCriteria);

            while (elementEnumerator.MoveNext())
            {
                BIM.LineStyle lineStyle = elementEnumerator.Current.LineStyle;
            }
        }

It appears that all my custom & Bentley linestyle numbers are negative if found (except 0-9), if they are missing, they show a postive number greater than 9.

Wanted to see if anyone can confirm this is correct?

I'll need to handle the cases where the linestyle is set to By-Level then handle that by going thru the LineStyleManager object.

Tried doing this thru the DgnNET methodology but can figure out. 

  • Hi  ,

    Without a sample dgn and possibly an associated linestyle resource file having negative numbers to test with; I cannot (with certainty) verify if the results of the code snippet above will produce correct results or not.

    Possibly rhetorical, though...

    In general, I am curious why; being a C# app (primarily?); you do not iterate the design file with the managed .NET APIs and use the ElementPropertiesGetter/ElementPropertiesSetter methods and respective LineStyle property directly.

    With respect to "other positive numbers" the DgnPlatformNet.chm Help Topic: "LsKnownStyleNumber Enumeration" provides some "expected" (positive and negative) line style number values; where possibly (your) additional negative numbers may also be passed/permitted through as well:

    LsKnownStyleNumber Enumeration

    Member name

    Value

    Description

    MinLineCode

    0

     

    MaxLineCode

    7

     

    ByLevel

    2147483647

     

    ByCell

    2147483646

     

    Invalid

    2147483392

     

    The MicroStation SDK does provide one native code example using the ElementPropertiesGetter with LineStyle properties; that may provide some additional level of details that could be helpful and methods/properties (having very similar names) in the .NET API.

    Elements\ElementsExample\ElementsExampleQueryTool.cpp:143:WString ElementsQueryHelper::QueryElementDisplay (ElementHandleCR eh)

    HTH,
    Bob.



  • "In general, I am curious why; being a C# app (primarily?); you do not iterate the design file with the managed .NET APIs and use the ElementPropertiesGetter/ElementPropertiesSetter methods and respective LineStyle property directly."

    In general, we try to go the managed .NET route, but it is not nearly as clear or quick. I had a full COM solution in 5 minutes compared to hours in NET (still no resolution)

    Alot of this is due to the very limited documentation for .NET. I read the API documentation and might find what I'm looking for, but then the .NET objects sometimes don't have the same properties/methods exposed for many objects. (they may be there but hidden in some obscure dll that unless it is included in the project the Visual Studio Object Browser can't find it)

     In COM: 

    BIM.LineStyle lineStyle = Bentley.MstnPlatformNET.InteropServices.Utilities.ComApp.ActiveDesignFile.LineStyles.Find(element.LineStyle.Name, null);

    will return a null if the style cannot be found (what I need to know).

    In NET I can't figure any comparable functionallity (yet), still trying though.

    Tried the following code that seems similar but I'm not finding any return results that let me know the style is missing.

    ElementPropertiesGetter elementPropertiesGetter = new ElementPropertiesGetter(element);
    LineStyleParameters lsp = elementPropertiesGetter.LineStyle;
    int lsId = elementPropertiesGetter.LineStyleId;
    string lsName = LineStyleManager.GetNameFromNumber(lsId, Session.Instance.GetActiveDgnFile());
    int lsNumber = LineStyleManager.GetNumberFromName(lsName, Session.Instance.GetActiveDgnFile());
    
    LsDgnFileMap lsDgnFileMap = Session.Instance.GetActiveDgnFile().GetLineStyleMap();
    LsMapEntriesCollection mapEntries = lsDgnFileMap.GetLsMapEntries();

  • I think I have it working using the .NET API, still testing and need to do some cleanup & commenting.

           public static void GetLineTypeNET(string unparsed)
            {
                ModelElementsCollection elements = Session.Instance.GetActiveDgnModel().GetGraphicElements();
    
                foreach (Element element in elements)
                {
                    bool styleFound = LineStyleFoundNET(element);
                }
            }
    
            public static bool LineStyleFoundNET(Element element)
            {
                DgnFile dgnFile = element.DgnModel.GetDgnFile();
    
                ElementPropertiesGetter elementPropertiesGetter = new ElementPropertiesGetter(element);
                int lsNum = elementPropertiesGetter.LineStyleId;
                LineStyleParameters lsp = elementPropertiesGetter.LineStyle;
                int lsId = elementPropertiesGetter.LineStyleId;
                string lsName = LineStyleManager.GetStringFromNumber(lsId, Session.Instance.GetActiveDgnFile());
    
                if (lsName.ToLower() == "style_bylevel")
                {
                    lsName = GetByLevelLineStyleNameNET(element);
                }
    
                if (lsName != "0" && lsName != "1" && lsName != "2" && lsName != "3" && lsName != "4" && 
                    lsName != "5" && lsName != "6" && lsName != "7" && lsName != "8" && lsName != "9")
    
                {
                    LsDgnFileMap lsDgnFileMap = dgnFile.GetLineStyleMap();
                    LsSystemMap lsSystemMap = Bentley.DgnPlatformNET.LsSystemMap.GetSystemMap();
                    LsMapEntriesCollection lsMapEntries = lsSystemMap.GetLsMapEntries();
    
                    foreach (LsMapEntry lsMapEntry in lsMapEntries)
                    {
                        if (lsMapEntry.StyleName == lsName)
                        {
                            return true;
                        }
                    }
                    return false;
                }
                else
                {
                    return true;
                }
            }
    
            public static string GetByLevelLineStyleNameNET(Element element)
            {
                DgnFile dgnFile = element.DgnModelRef.GetDgnFile();
                LevelCache levelCache = dgnFile.GetLevelCache();
                LevelHandle levelHandle = levelCache.GetLevel(element.LevelId);
                LevelDefinitionLineStyle levelDefinitionLineStyle = levelHandle.GetByLevelLineStyle();
    
                LsDgnFileMap lsDgnFileMap = dgnFile.GetLineStyleMap();
                int lsCode = levelDefinitionLineStyle.Style;
                if (lsCode < 0 || lsCode > 9)
                {
                    LsEntry lsEntry = lsDgnFileMap.GetLineStyleEntry(lsCode);
                    return lsEntry.StyleName;
                }
                else
                {
                    return lsCode.ToString();
                }
            }

    2 days for NET compared to 5 minutes to write the same code in COM.

  • this is due to the very limited documentation for .NET

    The .NET API documentation is not limited: there are five separate .NET help documents!  The problem is deciding which one provides the help you need.

    I agree that the .NET documentation is terse.  It's like a dictionary, which provides a definition of a word but no direction on how to construct a sentence that uses your word.

    When you get stuck with .NET documentation, take a look at the C++ MicroStationAPI help.  That (single) document contains examples for some classes, and more explanation than the .NET documents.  Many .NET classes are wrappers around a C++ class having the same or similar name.

     
    Regards, Jon Summers
    LA Solutions