An exception occurs when the input is deleted

I am creating a component that adds and deletes Inputs based on the number of Geometry faces.

Adding Inputs is fine, but when an Input is deleted, the following exception occurs.

Index was out of range. Must be non-negative and less than the size of the collection.

I don’t know what is causing the exception, but is it necessary after deleting the Input?

DynamicInput01Component.cs (4.8 KB)

I used the GH_Document.ScheduleSolution Method to solve the problem, with reference to the following thread.

I’ve attached my code.
This code implements IGH_VariableParameterComponent, but it may work without it.

using System;
using System.Collections.Generic;

using Grasshopper.Kernel;
using Grasshopper.Kernel.Parameters;
using Rhino.Geometry;
using System.Drawing;
using Grasshopper;

namespace MyGrasshopperAssembly1.DynamicInput
{
    public class DynamicInput02Component : GH_Component, IGH_VariableParameterComponent
    {
        /// <summary>
        /// Initializes a new instance of the DynamicInput02Component class.
        /// </summary>
        public DynamicInput02Component()
          : base("Dynamic Input 02", "DInp",
              "Description",
               "MyGHA", "Primitive")
        {
            VariableParameterMaintenance();
        }

        /// <summary>
        /// Registers all the input parameters for this component.
        /// </summary>
        protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
        {
            pManager.AddGeometryParameter("Geometry", "G", "Input Geometry", GH_ParamAccess.item);
        }


        /// <summary>
        /// Registers all the output parameters for this component.
        /// </summary>
        protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
        {
            pManager.AddGeometryParameter("Result", "R", "Result", GH_ParamAccess.item);
            pManager.AddTextParameter("Info", "I", "Info", GH_ParamAccess.item);
        }
        
        
        private int faceCount = 0;

        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA) 
        {
            try
            {
                var geo = new Brep();
                if (!DA.GetData(0, ref geo)) return;

                int newFaceCount = geo.Faces.Count;
                if (newFaceCount != faceCount)
                {
                    //faceCount = newFaceCount;
                    GH_Document gdoc = Instances.ActiveCanvas.Document;
                    gdoc.ScheduleSolution(0, CallBack);
                    faceCount = newFaceCount;
                }
                else
                {
                    List<Color> colors = new List<Color>();
                    for (int i = 0; i < faceCount; i++)
                    {
                        Color color = Color.White;
                        DA.GetData(i + 1, ref color); // Face count is 1-based
                        colors.Add(color);
                    }

                    DA.SetData(0, geo);

                    string result = "Received " + colors.Count + " colors.";
                    // color to strings
                    foreach (Color color in colors)
                    {
                        result += "\n" + color.ToString();
                    }
                    DA.SetData(1, result);
                }
            }
            catch (Exception e)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e.Message);
            }
        }

        public void CallBack(GH_Document gH_Document)
        {
            //Variable Parameter Maintenance            

            // Remove all existing inputs
            while (Params.Input.Count > 1)
            {
                var i = Params.Input.Count - 1;
                Params.Input[i].Sources.Clear();
                Params.UnregisterInputParameter(Params.Input[i]);
                Params.OnParametersChanged();
            }

            // Add new inputs
            for (int i = 0; i < faceCount; i++)
            {
                // Create and add a new Input
                var inp = new Param_Colour()
                {
                    Name = "Color " + (i + 1),
                    NickName = "C" + (i + 1),
                    Description = "Color for face " + (i + 1),
                    Access = GH_ParamAccess.item,
                    Optional = true
                };
                Params.RegisterInputParam(inp);
            }

            Params.OnParametersChanged();
            VariableParameterMaintenance();
            this.ExpireSolution(true);
        }

        public override void AddedToDocument(GH_Document document)
        {
            base.AddedToDocument(document);
        }

        public bool CanInsertParameter(GH_ParameterSide side, int index)
        {
            return false;
        }

        public bool CanRemoveParameter(GH_ParameterSide side, int index)
        {
            return false;
        }

        public IGH_Param CreateParameter(GH_ParameterSide side, int index)
        {
            return new Param_GenericObject();
        }

        public bool DestroyParameter(GH_ParameterSide side, int index)
        {
            return true;
        }
        public void VariableParameterMaintenance()
        {
            //for (int i = 1; i < this.Params.Input.Count; i++)
            //{
            //    this.Params.Input[i].Name = (i - 1).ToString();
            //    this.Params.Input[i].NickName = (i - 1).ToString();
            //}
        }

        /// <summary>
        /// Provides an Icon for the component.
        /// </summary>
        protected override System.Drawing.Bitmap Icon
        {
            get
            {
                //You can add image files to your project resources and access them like this:
                // return Resources.IconForThisComponent;
                return null;
            }
        }

        /// <summary>
        /// Gets the unique ID for this component. Do not change this ID after release.
        /// </summary>
        public override Guid ComponentGuid
        {
            get { return new Guid("CF6292BC-A312-425D-B51C-1D1897B73E52"); }
        }
    }
}