Update Param Size after IconDisplayMode Change

What method can I call on a GH.DocumentObject to update its presentation on the canvas?

I am trying to change all the input and output params of a group to override the IconDisplayMode (I work in icon mode but used named params for I/O). The Icon Display change is working, but the size does not update to the change until the param is moved.

How do I trigger the params to update their size? I’ve looked through the methods and properties on the IGH_DocumentObject Interface to no avail.

Icon to Text:

Text to Icon:

IconDisplayMode.gh (6.2 KB)

Bones of this code for gathering and modifying params in a group came from @qythium a few years back: Two tiny gripes - #21 by qythium

Have you tried GH_DocumentObject.OnObjectChanged? Pass it IconDisplayMode member of the GH_ObjectEventType enum.

I haven’t - not successfully at least. Not sure where to implement that.
I did find a workaround, but it’s a kludge - ExpireSolution on the object does get the size to change, but it also recalculates the solution on that component, which is less helpful.

    var grps = GrasshopperDocument.SelectedObjects().OfType<Grasshopper.Kernel.Special.GH_Group>();

    foreach(var grp in grps){
      var objs = grp.ObjectsRecursive();
      var prms = new List<IGH_Param>();

      foreach(var obj in objs) {
        var comp = obj as GH_Component;
        if (comp != null) {
          prms.AddRange(comp.Params);
          continue;
        }
        var prm = obj as IGH_Param;
        if (prm != null) prms.Add(prm);
      }

      var incoming = prms.Where(p => p.Sources.Any(s => !prms.Contains(s)));
      var outgoing = prms.Where(p => p.Recipients.Any(s => !prms.Contains(s)));
      if (y == true)
      {
        foreach (IGH_Param p in incoming)
        {
          //Something here? 
          //tried p.OnObjectChanged(GH_ObjectEventType.IconDisplayMode), no luck)
          p.IconDisplayMode = GH_IconDisplayMode.name;
          p.ExpireSolution(true)   //This works, but has unpleasant side effects
        }
        foreach (IGH_Param p in outgoing)
        {
          p.IconDisplayMode = GH_IconDisplayMode.name;
          p.ExpireSolution(true)  
        }
      }
      else
      {
        foreach (IGH_Param p in incoming)
        {
          p.IconDisplayMode = GH_IconDisplayMode.icon;
        }
        foreach (IGH_Param p in outgoing)
        {
          p.IconDisplayMode = GH_IconDisplayMode.icon;
        }
      }

    }

Ok, now I also checked your actual code in the GH definition you uploaded.

All you need to do is after each p.IconDisplayMode change call p.OnAttributesChanged() - this triggers the necessary event. Flipping boolean input now will automatically update the icon display mode.

Hmmm… I tried, but it doesn’t seem to work. Param overall size still matches the previous setting.

Ah I now realize that you are talking about the visual size of the component. For some reason I thought you were talking about the icon was not working properly.

Yes, sorry if I didn’t explain that clearly.

Have you solved this question? Maybe you can try to replace “p.ExpireSolution(true)” as “p.Attributes.ExpireLayout()”

Thank you! This worked perfectly.

Tightened up the code, here’s the result:

Description: component for setting the icon display of inputs and outputs of a group on the canvas.
Instructions: select one or more groups and trigger the component to set the target group(s)

inputs are:

  1. button which acts as a trigger, and a value list set to:
  2. Value List “mode” set to: [Application = “0”, Icon = “1”, Name = “2”]

 private void RunScript(object run, int mode, ref object A)
  {
    var grps = GrasshopperDocument.SelectedObjects().OfType<Grasshopper.Kernel.Special.GH_Group>();

    foreach(var grp in grps){
      var objs = grp.ObjectsRecursive();
      var prms = new List<IGH_Param>();

      foreach(var obj in objs) {
        var comp = obj as GH_Component;
        if (comp != null) {
          prms.AddRange(comp.Params);
          continue;
        }
        var prm = obj as IGH_Param;
        if (prm != null) prms.Add(prm);
      }
      var incoming = prms.Where(p => p.Sources.Any(s => !prms.Contains(s)));
      var outgoing = prms.Where(p => p.Recipients.Any(s => !prms.Contains(s)));
      
      foreach (IGH_Param p in incoming)
      {
        p.IconDisplayMode = (GH_IconDisplayMode) mode;
        p.Attributes.ExpireLayout();
      }
      foreach (IGH_Param p in outgoing)
      {
        p.IconDisplayMode = (GH_IconDisplayMode) mode;
        p.Attributes.ExpireLayout();
      }
    }
  }