c#, Problem placing fence on view/model

Hi,  I can not figure out how to place a fence in C# on another model.

This is with Bentley Map 08.11.09.864

The process is : 

1) Read the current fence information
2) Switch to another model
3) Place the fence in this model - same place as it was in the other one.

Here is what I'm trying :

BCOM.Fence oFence = null;
BCOM.Element oElement = null;

if (KortAddin.ComApp.ActiveDesignFile.Fence.IsDefined)
{
   oFence = KortAddin.ComApp.ActiveDesignFile.Fence;
   oElement = oFence.CreateElement();
   foreach (BCOM.ViewGroup vg in KortAddin.ComApp.ActiveDesignFile.ViewGroups)
    {
        if ((vg.Name.Length >= 6) && (vg.Name.Substring(0, 6) == ModelName))
        {
            if (!vg.Name.Contains("Temp Views"))
            {
                 vg.Activate();
                 _wfsModel = KortAddin.ComApp.ActiveModelReference;

                 KortAddin.ComApp.ActiveDesignFile.Fence.Undefine();
                 KortAddin.ComApp.ActiveDesignFile.Fence.DefineFromElement(oFence.View, oElement);

The last line is not working - throwing this error :
System.Runtime.InteropServices.COMException (0x80040000): Fence is not defined
at Bentley.Interop.MicroStationDGN.Fence.get_View()

If I change the code - and comment out the "vg.Activate" - so the model is not changed - everything is working ok.  But I need the defined fence in the current model - to be placed in another model.

Are the oFence and/or oElement destroyed somehow when switching the view/model ? and if so - how to make it work ?

Thanks for any input.

Parents
  • Hi Julian,

    at first, please read and follow this forum best practices and also common best practices. There are recommended rules defined about subject format and used tools (e.g. to use Insert > Insert code for EVERY shared code) that ensure the communication will be efficient and all necessary information will be shared from beginning.

    Also, I am not sure whether MicroStation Programming forum is the best place where to ask when Bentley Map is used. On the other hand the fence placement is probably more MicroStation topic than Bentley Map ;-)

    Here is what I'm trying :

    Honestly, the code is ugly ... but functional.

    I think the problem is, as you asked yourself, that fence instance is invalidated when another model is activated. It is how MicroStation works, so it should be not a surprise that when another model is activated, oFence.View throws exception (because oFence is not valid reference).

    and if so - how to make it work ?

    It's very simple: Fence is always shape, so remember the fence vertices and create a new fence using this list.

    Thanks for any input.

    A couple of comments to the shared code:

    • BCOM.Fence oFence = null; ... In C# all data types (both value and reference types) have exactly defined initial value. For reference types, it's null. No exception (the exception will exist in C# 8 where non-nullable reference types are introduced)! So to write BCOM.Fence oFence = null; makes no sense.
    • BCOM.Fence oFence = null; ... In the most of modern languages a rule "declare variable when it is necessary" is used. So both oFence and oElement variables should be declared inside the first condition, when they are used.
    • Naming style ... It's something pretty subjective, but you should be aware there are Microsoft guidelines available and Visual Studio analyzers are configured to follow these rules. To use names oFence (VBA style) or _wfsModel (C style) will be identified as violating these rules.
    • Three nested IFs ... I like the rule "when there is IF in IF, such code is wrong". And an aim is to have one IF in a method at max. Despite of the rules can be broken when necessary, to keep cyclomatic complexity as small as possible always lead to cleaner code.

    With regards,

      Jan

Reply
  • Hi Julian,

    at first, please read and follow this forum best practices and also common best practices. There are recommended rules defined about subject format and used tools (e.g. to use Insert > Insert code for EVERY shared code) that ensure the communication will be efficient and all necessary information will be shared from beginning.

    Also, I am not sure whether MicroStation Programming forum is the best place where to ask when Bentley Map is used. On the other hand the fence placement is probably more MicroStation topic than Bentley Map ;-)

    Here is what I'm trying :

    Honestly, the code is ugly ... but functional.

    I think the problem is, as you asked yourself, that fence instance is invalidated when another model is activated. It is how MicroStation works, so it should be not a surprise that when another model is activated, oFence.View throws exception (because oFence is not valid reference).

    and if so - how to make it work ?

    It's very simple: Fence is always shape, so remember the fence vertices and create a new fence using this list.

    Thanks for any input.

    A couple of comments to the shared code:

    • BCOM.Fence oFence = null; ... In C# all data types (both value and reference types) have exactly defined initial value. For reference types, it's null. No exception (the exception will exist in C# 8 where non-nullable reference types are introduced)! So to write BCOM.Fence oFence = null; makes no sense.
    • BCOM.Fence oFence = null; ... In the most of modern languages a rule "declare variable when it is necessary" is used. So both oFence and oElement variables should be declared inside the first condition, when they are used.
    • Naming style ... It's something pretty subjective, but you should be aware there are Microsoft guidelines available and Visual Studio analyzers are configured to follow these rules. To use names oFence (VBA style) or _wfsModel (C style) will be identified as violating these rules.
    • Three nested IFs ... I like the rule "when there is IF in IF, such code is wrong". And an aim is to have one IF in a method at max. Despite of the rules can be broken when necessary, to keep cyclomatic complexity as small as possible always lead to cleaner code.

    With regards,

      Jan

Children