c#_Create Value List GH Component for Custom GH Plugin

Hi,
How can I create value list like component in custom grasshopper plugin?
Normally Custom components are inherited from GH_Component but for value list like compoent what do I have to do? I have several value lists to create and i want to have them as components so they are always in the plugin. User shall not be able to edit the values of course.

Any direction to solve this would be really helpful.

Thanks!!!

public override void AddedToDocument(GH_Document document)
        {

            base.AddedToDocument(document);


            //Add Value List
            int[] stringID = new int[] { 1 };

            for (int i = 0; i < stringID.Length; i++)
            {
                Grasshopper.Kernel.Parameters.Param_String in0str = Params.Input[stringID[i]] as Grasshopper.Kernel.Parameters.Param_String;
                if (in0str == null || in0str.SourceCount > 0 || in0str.PersistentDataCount > 0) return;
                Attributes.PerformLayout();
                int x = (int)in0str.Attributes.Pivot.X - 250;
                int y = (int)in0str.Attributes.Pivot.Y - 10;
                Grasshopper.Kernel.Special.GH_ValueList valList = new Grasshopper.Kernel.Special.GH_ValueList();
                valList.CreateAttributes();
                valList.Attributes.Pivot = new PointF(x, y);
                valList.Attributes.ExpireLayout();
                valList.ListItems.Clear();

                List<Grasshopper.Kernel.Special.GH_ValueListItem> materials = new List<Grasshopper.Kernel.Special.GH_ValueListItem>()
        {
          new Grasshopper.Kernel.Special.GH_ValueListItem("silver ag 999", "10.49"),
          new Grasshopper.Kernel.Special.GH_ValueListItem("silver ag 925", "10.40"),
          new Grasshopper.Kernel.Special.GH_ValueListItem("white gold Au750Pd130", "15.80"),
          new Grasshopper.Kernel.Special.GH_ValueListItem("white gold Au750Pd150", "	15.90"),
          new Grasshopper.Kernel.Special.GH_ValueListItem("white gold Au750Pd210", "	16.30"),
          new Grasshopper.Kernel.Special.GH_ValueListItem("pale gold 2N Au750Ag160", "	15.60"),
          new Grasshopper.Kernel.Special.GH_ValueListItem("yellow gold 3N Au750Ag125", "	15.40"),
          new Grasshopper.Kernel.Special.GH_ValueListItem("rosé gold 4N Au750Ag90", "15.30"),
          new Grasshopper.Kernel.Special.GH_ValueListItem("red gold 5N Au750Ag45", "15.10"),
          new Grasshopper.Kernel.Special.GH_ValueListItem("most red gold 6N Au750Ag5Pt4", "15.10"),
          new Grasshopper.Kernel.Special.GH_ValueListItem("platine 950", "20.40"),
          new Grasshopper.Kernel.Special.GH_ValueListItem("palladium 950", "11.80")
          };
                valList.ListItems.AddRange(materials);
                document.AddObject(valList, false);
                in0str.AddSource(valList);
            }
        }

the user CAN change the values though by double clicking on the created value list. this will attach a new value list with prefdefined values when you drop your element on the canvas.

If you want to recreate a value list without the changing options, you have to build your own dropdown list etc in SpecialIntegerObject. ( I think)

I got here the SingleClickBoolean code that shows how to make custom elements (it’s a bit of a mess though):

using System;
using System.Collections.Generic;
using Grasshopper.Kernel;
using System.Drawing;
using Grasshopper.GUI;
using Grasshopper.GUI.Canvas;
using Grasshopper.Kernel.Types;

namespace projectPhoenix
{
    public class SpecialIntegerObject : GH_Param<GH_Boolean>
    {
        
        public SpecialIntegerObject() :
        base(new GH_InstanceDescription("toggle", "toggle", "True/False", "Params", "Input"))
        {

        }
        public override void CreateAttributes()
        {
            m_attributes = new SpecialIntegerAttributes(this);
        }
        protected override Bitmap Icon
        {
            get
            {
                return Properties.Resources.oneClick;
                ///return null;
            }
        }
        public override GH_Exposure Exposure
        {
            get
            {
                return GH_Exposure.primary | GH_Exposure.obscure;
            }
        }
        public override Guid ComponentGuid
        {
            get { return new Guid("140a4f90-b246-4c0d-9448-9e56212e5515"); }
        }
        private bool m_value;
        public bool Value
        {
            get { return m_value; }
            set { m_value = value; }
        }
        protected override void CollectVolatileData_Custom()
        {
            VolatileData.Clear();
            AddVolatileData(new Grasshopper.Kernel.Data.GH_Path(0), 0, new GH_Boolean(Value));
        }
        public override bool Write(GH_IO.Serialization.GH_IWriter writer)
        {
            writer.SetBoolean("SpecialInteger", m_value);
            return base.Write(writer);
        }
        public override bool Read(GH_IO.Serialization.GH_IReader reader)
        {
            reader.TryGetBoolean("SpecialInteger", ref m_value);
            return base.Read(reader);
        }
    }
    public class SpecialIntegerAttributes : GH_Attributes<SpecialIntegerObject>
    {
        public SpecialIntegerAttributes(SpecialIntegerObject owner)
        : base(owner)
        {
        }
        public override bool HasInputGrip { get { return false; } }
        public override bool HasOutputGrip { get { return true; } }
        private const int ButtonSize = 22;
        public bool bo;

        protected override void Layout()
        {
            Pivot = GH_Convert.ToPoint(Pivot);
            Bounds = new RectangleF(Pivot, new SizeF(Button().Width + 4 + 22, 22));
        }
        private Rectangle Button()
        {
            int x = Convert.ToInt32(Pivot.X);
            int y = Convert.ToInt32(Pivot.Y);
            return new Rectangle(x  +24, y + 2, 46, 18);
        }
        public override GH_ObjectResponse RespondToMouseDown(GH_Canvas sender, GH_CanvasMouseEvent e)
        {
            //On one click we'll set the owner value.
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
            {
                RectangleF button = Button();
                if (button.Contains(e.CanvasLocation))
                {
                    bo = bo ? false : true;
                    Owner.RecordUndoEvent("value Change");
                    Owner.Value = bo;
                    Owner.ExpireSolution(true);
                    return GH_ObjectResponse.Handled;
                }
            }
            return base.RespondToMouseDown(sender, e);
        }
        /// <summary>
        /// </summary>
        protected override void Render(GH_Canvas canvas, Graphics graphics, GH_CanvasChannel channel)
        {
            bo = Owner.Value ? true : false;
            GH_CapsuleRenderEngine.RenderOutputGrip(graphics, canvas.Viewport.Zoom, OutputGrip, true);
            Rectangle button = Button();
            GH_Capsule cap = GH_Capsule.CreateCapsule(new RectangleF(Pivot, new SizeF(Button().Width+4+22, 22)), GH_Palette.Transparent,3,8);

            cap.Render(graphics, Color.LightSlateGray);
            cap.Dispose();

            GH_Capsule capsule = GH_Capsule.CreateTextCapsule(button, button, GH_Palette.Black, bo.ToString(), new Font("Courier New",10),1,1);
            capsule.HighlightShape.Reset();
            capsule.Render(graphics, Selected, Owner.Locked, false);
            capsule.Dispose();

            Rectangle rnd = new Rectangle(Convert.ToInt32(Pivot.X) + 2, Convert.ToInt32(Pivot.Y) + 2, ButtonSize - 4, ButtonSize - 4);
            Color color = Owner.Value ? Color.Green : Color.Red;
            GH_Capsule buttonb = GH_Capsule.CreateCapsule(rnd, GH_Palette.Transparent, ButtonSize/2, 10);
            buttonb.HighlightShape.Reset();
            buttonb.HighlightShape.AddPie(rnd, 180f, 180f);
            buttonb.Render(graphics, color);

            buttonb.Dispose();
        }
    }
}

hope this helps

Ben