# Convert IDictionary to Dictionary for ZeroTouchNode

**URL:** <https://forum.dynamobim.com/t/convert-idictionary-to-dictionary-for-zerotouchnode/101208>\
**Category:** Revit\
**Tags:** zerotouch, dynamo, csharp\
**Created:** [May 22, 2024, 11:39am UTC](https://forum.dynamobim.com/t/convert-idictionary-to-dictionary-for-zerotouchnode/101208 "2024-05-22T11:39:31Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![lrsmns](https://avatars.discourse-cdn.com/v4/letter/l/d2c977/32.png) [@lrsmns](https://forum.dynamobim.com/u/lrsmns)\
**Post date:** [May 22, 2024, 11:39am UTC](https://forum.dynamobim.com/t/convert-idictionary-to-dictionary-for-zerotouchnode/101208/1 "2024-05-22T11:39:31Z")

</div>

Hi i’m trying to create a ZeroTouchNode that takes Dictionary as an input, and displays the keys as a dropdown combo box, and the values from the selected key in textboxes under.

I know that firslty the type from dynamo (IDictionary) needs to be translated to Dictionary for windows system.

As i referred from existing forum post: [Input a dictionary from dynamo (DesignScript.Builtin.Dictionary) to a custom ZeroTouch node - Developers - Dynamo (dynamobim.com)](https://forum.dynamobim.com/t/input-a-dictionary-from-dynamo-designscript-builtin-dictionary-to-a-custom-zerotouch-node/75577/7)

this is what i have so far:

```auto
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.DesignScript.Runtime;
using Autodesk.DesignScript.Interfaces;

namespace PrintedGeometryGUI
{
    public class PrintingFormNode
    {
        public List<object> UI(IDictionary<string, List<int>> MaterialComposition)
        {
            List<object> listReturn = new List<object>();
            Dictionary<string, List<int>> materialComposition = DictionaryUtility.ConvertToDictionary(MaterialComposition);

            PrintingForm window = new PrintingForm(materialComposition);
            var res = window.ShowDialog();

            if (res.HasValue && res.Value)
            {
                string selectedKey = window.comboBox_material.SelectedItem.ToString();
                if (materialComposition.TryGetValue(selectedKey, out List<int> values))
                {
                    listReturn.Add(selectedKey);
                    listReturn.Add(values[0]); 
                    listReturn.Add(values[1]); 
                    listReturn.Add(values[2]); 
                }
            }

            return listReturn;
        }
    }
}

```

To which this is to convert the dictionary type:

```auto
using System.Collections.Generic;
using System.Linq;

namespace PrintedGeometryGUI
{
    public static class DictionaryUtility
    {
        public static Dictionary<string, List<int>> ConvertToDictionary(IDictionary<string, List<int>> inputDictionary)
        {
            Dictionary<string, List<int>> convertedDictionary = new Dictionary<string, List<int>>();

            foreach(var entry in inputDictionary) 
            { 
                convertedDictionary[(string)entry.Key] = (List<int>)entry.Value; 
            }
            return convertedDictionary;
        }

    }
}

```

And my windows form class:

```auto
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;

namespace PrintedGeometryGUI
{
    /// <summary>
    /// Interaktionslogik für UserControl1.xaml
    /// </summary>
    public partial class PrintingForm : Window
    {
        private Dictionary<string, List<int>> materialComposition;

        public PrintingForm(Dictionary<string, List<int>> materialComposition)
        {
            InitializeComponent();
            this.materialComposition = materialComposition;
            comboBox_material.ItemsSource = materialComposition.Keys;
        }

        private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (comboBox_material.SelectedItem != null)
            {
                string selectedKey = comboBox_material.SelectedItem.ToString();
                if (materialComposition.TryGetValue(selectedKey, out List<int> values))
                {
                    
                    if (values.Count >= 3)
                    {
                        densityTextBox.Text = values[0].ToString();
                        initialYieldStressTextBox.Text = values[1].ToString();
                        structuralBuildUpRateTextBox.Text = values[2].ToString();
                    }
                }
            }
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            DialogResult = true;
        }

        private void cancel_button_Click(object sender, RoutedEventArgs e)
        {
            DialogResult = false;
            Close();
        }
    }
}

```

My node is giving an error saying “At least one element from source array could not be converted to target array type.”

Would appreciate any insights and help!

---

<div class="post-metadata">

**Author:** ![Mike.Buttery](https://avatars.discourse-cdn.com/v4/letter/m/b19c9b/32.png) [@Mike.Buttery](https://forum.dynamobim.com/u/Mike.Buttery)\
**Post date:** [May 24, 2024, 12:01am UTC](https://forum.dynamobim.com/t/convert-idictionary-to-dictionary-for-zerotouchnode/101208/2 "2024-05-24T00:01:59Z")

</div>

Are all your list values integer type?

---

<div class="post-metadata">

**Author:** ![emrullah.yildiz](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/emrullah.yildiz/32/177572_2.png) [@emrullah.yildiz](https://forum.dynamobim.com/u/emrullah.yildiz)\
**Post date:** [June 3, 2024, 12:18pm UTC](https://forum.dynamobim.com/t/convert-idictionary-to-dictionary-for-zerotouchnode/101208/3 "2024-06-03T12:18:32Z")

</div>

I would suggest to implement more checks on your ConvertToDictionary method. You can try something like this to see if the error is related with your input list:

```auto
public static Dictionary<string, List<int>> ConvertToDictionary(IDictionary<string, List<int>> inputDictionary)
        {
            var convertedDictionary = new Dictionary<string, List<int>>();

            // Check if inputDictionary is null
            if (inputDictionary == null)
            {
                throw new ArgumentNullException(nameof(inputDictionary), "Input dictionary cannot be null.");
            }

            // Iterate over the input dictionary and check types
            foreach (var entry in inputDictionary)
            {
                if (!(entry.Key is string))
                {
                    throw new InvalidCastException($"Key '{entry.Key}' is not of type string.");
                }

                if (!(entry.Value is List<int>))
                {
                    throw new InvalidCastException($"Value for key '{entry.Key}' is not of type List<int>.");
                }

                convertedDictionary[entry.Key] = entry.Value;
            }

            return convertedDictionary;
        }

```

---

<div class="post-metadata">

**Author:** ![c.poupin](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.dynamobim.com/c.poupin/32/89152_2.png) [@c.poupin](https://forum.dynamobim.com/u/c.poupin)\
**Post date:** [June 3, 2024, 7:42pm UTC](https://forum.dynamobim.com/t/convert-idictionary-to-dictionary-for-zerotouchnode/101208/4 "2024-06-03T19:42:20Z")

</div>

I’m not a C# expert, but the urge to test the implementation of the MVVM pattern on a ZT node was too great.

And this topic is ideal for this exercise

here’s my solution with MVVM

> **[GitHub - Cyril-Pop/Example\_ZeroNode\_with\_MVVM: a simple Test of a DynamoBim...](https://github.com/Cyril-Pop/Example_ZeroNode_with_MVVM)**
>
> a simple Test of a DynamoBim Zero Touch Node with WPF vand MVVM pattern - Cyril-Pop/Example\_ZeroNode\_with\_MVVM

![](https://us1.discourse-cdn.com/flex022/uploads/dynamobim/original/3X/8/9/89cc55eab02c8c774f8794221862b140c7b3c278.gif)

---

<div class="post-metadata">

**Author:** ![stillgotme](https://avatars.discourse-cdn.com/v4/letter/s/e480ec/32.png) [@stillgotme](https://forum.dynamobim.com/u/stillgotme)\
**Post date:** [June 4, 2024, 8:15am UTC](https://forum.dynamobim.com/t/convert-idictionary-to-dictionary-for-zerotouchnode/101208/5 "2024-06-04T08:15:36Z")

</div>

> [@emrullah.yildiz](#):
>
> `ConvertToDictionary`

hello there,  
first, can you specifically show which line is causing the error? and instead of just showing the error from the node… without identifying which line is causing the error, it is a little bit hard to pinpoint the actual mistake.

second, you can use `new Dictionary<string, List<int>>(MaterialComposition)` to convert it into a `Dictionary` class instead of using your converter. Still, from your use case, I don’t see a need to convert it into a `Dictionary` class since there is no merit to it. (you are just using key and value which can be accessed via the `IDictionary` interface)

third, you should be using `Class` and `ICollection` instead of `IDictionary` for a better “best practice” when doing WPF-related stuff. By using `List<Material>`, where `Material` is a class that contains your custom property, conversion ain’t required which means no error will happen 😃  
Example:

```auto
public class Material
{
    public string Name;
    public int Property1;
    public int Property2;
    public int Property3;
}

```

```auto
public Material UI(IDictionary<string, List<int>> MaterialComposition)
{
    List<Material> materials = new List<Material>();
    foreach(var item in MaterialComposition)
    {
        var value = item .Value;
        Material material = new Material()
        {
            Name = item.Key,
            Property1 = value[0],
            Property2 = value[1],
            Property3 = value[2],
        };
        materials.Add(material);
    }
    PrintingForm window = new PrintingForm(materials);
    //Continue to do your things
    ...
    ...
    ...
    //Finish doing your thing
    Material selectedItem = window.comboBox_material.SelectedItem;
    return selectedItem;
}

```

lastly, I would use a MultiReturn instead of List for your node (looks nicer and neater 🙂 )
