Iterating over a NameValueMap in Autodesk Inventor

1k views Asked by At

I tried iterating over a NameValueMap using a 0-based index but it did not work. Iterating over it using a 1-based index worked.

Did not work.

public static void onParameterChange(_Document document,
                                     Inventor.Parameter parameter,
                                     EventTimingEnum BeforeOrAfter,
                                     NameValueMap context ,
                                     out HandlingCodeEnum handlingCode)
{
   handlingCode = HandlingCodeEnum.kEventHandled;

   // Did not work. Got an exception.
   for ( int i = 0; i < context.Count; ++i )
   {
      string name = context.Name[i];
      string value = (string)context.Value[name];
   }
}

Worked.

public static void onParameterChange(_Document document,
                                     Inventor.Parameter parameter,
                                     EventTimingEnum BeforeOrAfter,
                                     NameValueMap context ,
                                     out HandlingCodeEnum handlingCode)
{
   handlingCode = HandlingCodeEnum.kEventHandled;

   // Worked.
   for ( int i = 1; i <= context.Count; ++i )
   {
      string name = context.Name[i];
      string value = (string)context.Value[name];
   }
}

I was surprised by that. Is that expected?

I also noticed that NameValueMap inherits IEnumerable. I tried using foreach to get the items of the NameValueMap. However, that only gave me the values of the items. Is there a way to get the names of the items as well?

public static void onParameterChange(_Document document,
                                     Inventor.Parameter parameter,
                                     EventTimingEnum BeforeOrAfter,
                                     NameValueMap context ,
                                     out HandlingCodeEnum handlingCode)
{
   handlingCode = HandlingCodeEnum.kEventHandled;

   foreach ( var item in context )
   {
      // How do you get the name?
      string value = item;
   }
}
2

There are 2 answers

3
Xiaoy312 On BEST ANSWER

There is little information on this NameValueMap on the internet, so it is hard to tell if there is an existing method to take advantage of.

However, you can always create an extension method to suit your needs:

public static class NameValueMapExtensions
{
    public static IEnumerable<KeyValuePair<object, T>> AsEnumerable<T>(this NameValueMap map)
    {
        for (int i = 1; i <= map.Count; i++)
            yield return new KeyValuePair<object, T>(
                map.Name[i], (T)map.Values[map.Name[i]]);
    }
}

// ...

foreach (var item in context.AsEnumerable())
{
    // item.Key: Name
    // item.Value: ...
}
0
Alain On

As NameValueMaps do not contain lots of elements, you could also just return a complete Dictionary, instead of yielding KeyValuePair elements. This gives you access to some handy methods, such as .TryGetValue().

public static class NameValueMapExtensions
{
    public static IDictionary<string, object> ToDictionary(this NameValueMap nameValueMap)
    {
        var dictionary = new Dictionary<string, object>();
        for (var i = 1; i <= nameValueMap.Count; i++)
            dictionary.Add(nameValueMap.Name[i], nameValueMap.Value[nameValueMap.Name[i]]);
        return dictionary;
     }
}