[CONNECT UPDATE 15 C#] LineStyle Scale

Hello,

I have problem with setting scale for linestyle in c#. If anyone found working solution please share it.

So far I tried to use ElementPropertiesSetter SetLineStyle function because this function takes LineStyleParameters as param but i can't create LineStyleParameters because it does not have constructor.

I tried to get LineStyleParameters from ElementPropertiesGetter and I get some but I can't change Scale for that object, it stays unchanged after lineStyle.Scale = scale.

Regards.

Parents
  • Hi Damian,

    but i can't create LineStyleParameters because it does not have constructor.

    When you will check documentation carefully (and e.g. will evaluate classes dependencies), you will find that LineStyleParameters are part of element display parameters, so they have to be obtained from there. In this situation the constructor makes no sense, because display parameters exists only when element is is displayable. And some parameters (as LineStylesParameters for example) exist only in certain situations, like when linear element has line style assigned.

    I can't change Scale for that object, it stays unchanged after lineStyle.Scale = scale.

    My feeling is that it does not work. I do not know whether it's a bug in API implementation or wrong code is used, but even with LineStyleParameters existing, it does not work for me (but maybe I did something wrong).

    I don't know how this "byLevel" feature works.

    It's crucial MicroStation (and also AutoCAD) feature, so this knowledge is mandatory, because represented in many aspects of MicroStation API.

    I need to set this value codebehind:

    Because I can see this value (LSScale) in EC schemas delivered with MicroStation, it should be accessible as element's EC property. And because it's not defined as read-only, I am pretty sure you can change it this way (which is popular and common workaround when a feature is not accessible or not work in API ;-)

    Regards,

      Jan

  • Hi Jan,

    If you provided a code with an example of using EC property, I would be grateful.

  • Hi Damian,

    please distinguish between Jon and Jan ;-)

    If you provided a code with an example of using EC property, I would be grateful.

    Sorry, in this case I am not willing to share snippet, because I wrote it as a part of commercial code that somebody else paid already.

    But because to understand EC representation of MicroStation data has become crucial knowledge, you can find many examples at many places (even when probably not exactly about Line Style properties):

    • MicroStation Programming blog: there are several articles how to work with ItemType (EC data subset) and also normal EC data
    • MicroStation Programming forum: Unlike this general programming forum, in MicroStation forum, DgnECManager, which is popular tool how to access element properties, was discussed many times.
    • MicroStation SDK: There are complete folder of examples (DgnEC), demonstrating how to work with different aspects of EC data both in C++ and NET.

    With regards,

      Jan

  • Hi Jan,

    I found some code in examples and I tried two ways to set LSScale for element but it doesn't work for me.

    In first attempt I tried DgnECInstanceEnabler but ObtainInscanceEnabler returns null for me.

    string schemaName = "BaseElementSchema";
    BNET.DgnEC.FindInstancesScope scope = BNET.DgnEC.FindInstancesScope.CreateScope(element, new BNET.DgnEC.FindInstancesScopeOption(DgnECHostType.Element, true));
    IECSchema schema = DgnECManager.Manager.LocateSchemaInScope(scope, schemaName, 1, 0, SchemaMatchType.Latest);
    
    if (schema != null)
    {
        var class1 = schema.GetClass("LineStyleParametersStruct") as ECClass;
        DgnECInstanceEnabler instanceEnabler = DgnECManager.Manager.ObtainInstanceEnabler(Session.Instance.GetActiveDgnFile(), class1);
        if (instanceEnabler != null)
        {
            StandaloneECDInstance instance = instanceEnabler.SharedWipInstance;
            instance.MemoryBuffer.SetDoubleValue("LSScale", -1, Util.GetScale(dgnModel));
            instanceEnabler.CreateInstanceOnElement(element, instance, false);
        }
    }

    In second one I tried to use ECQuery to FindInstanced but it doesn't find any.

    List<IECClass> classes = new List<IECClass>();
    string schemaName = "BaseElementSchema";
    BNET.DgnEC.FindInstancesScope scope = BNET.DgnEC.FindInstancesScope.CreateScope(element, new BNET.DgnEC.FindInstancesScopeOption(DgnECHostType.Element, true));
    IECSchema schema = DgnECManager.Manager.LocateSchemaInScope(scope, schemaName, 1, 0, SchemaMatchType.Latest);
    
    if (schema != null)
    {
        classes.Add(schema.GetClass("LineStyleParametersStruct"));
        ECQuery query = new ECQuery(classes);
        using (DgnECInstanceCollection ecInstances = DgnECManager.Manager.FindInstances(scope, query))
        {
            var instance = ecInstances.FirstOrDefault();
            if (instance != null)
            {
                instance.SetDouble("LSScale", Util.GetScale(dgnModel));
            }
        }
    }

    Any tip what I am doing wrong?

  • Any tip what I am doing wrong?

    I guess you are searching for wrong class name, but without some debugging, it's hard to say.

    But you choose, in my opinion, the most complicated way. To use ECQuery is powerful, but it requires to know exactly how ECQuery works (not very intuitive, because more graph than query) and also the structure of queried data. The problem is that hide complex logic, so when anything is wrong, it's usually not simple to find out what.

    Even when maybe less efficient, to use DgnECManager.GetElementProperties() is far simpler. Moreover, it allows easily understand, what EC classes and properties are available at specific element. Sometimes there is even no reason to rewrite code to ECQuery later, because it "just work".

    The only disadvantage of GetElementProperties (but it can be applied to all EC API) is a requirement to cast values to proper data type to access relevant methods. But it's common problem of OOP, when interfaces and inheritance is used. In the discussed case, everything is IECPropertyValue, but individual items can be containers like structures or arrays. But, fortunately, every IECPropertyValue knows what type it represents ;-)

    Regards,

      Jan

Reply
  • Any tip what I am doing wrong?

    I guess you are searching for wrong class name, but without some debugging, it's hard to say.

    But you choose, in my opinion, the most complicated way. To use ECQuery is powerful, but it requires to know exactly how ECQuery works (not very intuitive, because more graph than query) and also the structure of queried data. The problem is that hide complex logic, so when anything is wrong, it's usually not simple to find out what.

    Even when maybe less efficient, to use DgnECManager.GetElementProperties() is far simpler. Moreover, it allows easily understand, what EC classes and properties are available at specific element. Sometimes there is even no reason to rewrite code to ECQuery later, because it "just work".

    The only disadvantage of GetElementProperties (but it can be applied to all EC API) is a requirement to cast values to proper data type to access relevant methods. But it's common problem of OOP, when interfaces and inheritance is used. In the discussed case, everything is IECPropertyValue, but individual items can be containers like structures or arrays. But, fortunately, every IECPropertyValue knows what type it represents ;-)

    Regards,

      Jan

Children