Get data input from c# component without nickname

Hi everyone,
Is there a way to get data input for each input without using nickname? I am trying to make a c# component for which the nick name could be changed and the data for each input could still be read correctly.

I can access the nick name for each input as Component.Params.Input[inputCount].NickName

But how do I get the actual data? There is no DA.GetData() in the component I guess

Try

var string s;
DA.GetData(0, ref s); // first input = 0

// Rolf

I think DataAccess is not available in C# component.

Just found
Component.Params.Input[inputCount].VolatileData.AllData()

I was reading carelessly… sigh.

But you can use the following code in your C# component to mimmic compiled component’s DA accessor:

  // Cache for the GH_Component's DataAccess DA parameter.
  private IGH_DataAccess m_DA;

  // Mimicing the GH_Component's DataAccess DA parameter also outside
  // the SolveInstance method and provide a means to use the same code
  // syntax to ScriptComponents.
  private IGH_DataAccess DA
  {
    get {
      if (m_DA == null)
        m_DA = GetDataAccess();
      return m_DA;
    }
  }
  // Using Reflection to retrieve the GH_Component's DataAccess DA parameter.
  // This provides similar code syntax to ScriptComponents as is used by the
  // GH_Component's SolveInstance method parameter DA for getting and setting
  // Input/Output values (DA.GetData, DA.SetData). This code should only run
  // once since the Reflection loop is expensive. Code provided by David Rutten
  // in the following forum post:
  // https://discourse.mcneel.com/t/access-to-scriptcomponents-igh-dataaccess-da/64726/7
  private IGH_DataAccess GetDataAccess()
  {
    // Grasshopper.Kernel.GH_Component.GH_StructureIterator
    Type iteratorType = null;
    System.Reflection.Assembly ghAssembly = System.Reflection.Assembly.GetAssembly(typeof(Grasshopper.Instances));
    foreach (Type type in ghAssembly.GetTypes())
    {
      if (type.Name == "GH_StructureIterator")
      {
        iteratorType = type;
        break;
      }
    }

    object result = null;
    var TheType = iteratorType;

    if (iteratorType != null)
    {
      object iteratorInstance = null;
      foreach (System.Reflection.ConstructorInfo constructor in iteratorType.GetConstructors(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic))
      {
        iteratorInstance = constructor.Invoke(new object[] { Component });
        if (iteratorInstance != null)
          break;
      }

      var TheInstance = iteratorInstance;
      if (iteratorInstance != null)
      {
        result = iteratorInstance;
      }
    }
    return result as IGH_DataAccess ;
  }

// Rolf

Wow, this is great! Never think of it can be done like this. I tried item input with string and list input of int.

List testList = new List();
string testString = “”;
DA.GetData(0, ref testString);
DA.GetDataList(1, testList);

I am having error “Invalid cast: Number > Int32”. Any idea how to solve this? I am afraid the reflector is beyond my understanding.

If you set the multiplicity (item and list access) for each input on the capsule, the DataAccessor should just work. In the attachment below I ran the following code successfully:

    var s = "";
    DA.GetData(0, ref s);

    var str_list = new List<string>();
    DA.GetDataList(1, str_list);

    var int_list = new List<GH_Integer>();
    DA.GetDataList(2, int_list);

    StrList = str_list;
    IntList = int_list;

DataAccess example.gh (7.7 KB)

// Rolf

Hi Ril,

This is great help! Thank you. Now I can prototyping a component in c# scripting component first.

Xiaoming

1 Like