In a previous post I instantiated a slider automatically using only C#. This means it is possible for a component to add components to your canvas automatically, potentially saving a lot of time in many repetitive workflows.
Here is a similar piece of code, but for the Value List:
C# code
private void RunScript(bool x, List<object> y, ref object A) { if(x) { //instantiate new value list var vallist = new Grasshopper.Kernel.Special.GH_ValueList(); vallist.CreateAttributes(); //customise value list position int inputcount = this.Component.Params.Input[1].SourceCount; vallist.Attributes.Pivot = new PointF((float) this.Component.Attributes.DocObject.Attributes.Bounds.Left - vallist.Attributes.Bounds.Width - 30, (float) this.Component.Params.Input[1].Attributes.Bounds.Y + inputcount * 30); //populate value list with our own data vallist.ListItems.Clear(); var item1 = new Grasshopper.Kernel.Special.GH_ValueListItem("Red", "r"); var item2 = new Grasshopper.Kernel.Special.GH_ValueListItem("Green", "g"); var item3 = new Grasshopper.Kernel.Special.GH_ValueListItem("Yellow", "y"); vallist.ListItems.Add(item1); vallist.ListItems.Add(item2); vallist.ListItems.Add(item3); //Until now, the slider is a hypothetical object. // This command makes it 'real' and adds it to the canvas. GrasshopperDocument.AddObject(vallist, false); //Connect the new slider to this component this.Component.Params.Input[1].AddSource(vallist); } }
This code is written for the C# component in Grasshopper. If you are writing components within Visual Studio, there is a little extra work to do in defining GrasshopperDocument and Component, otherwise it’s pretty much a copy-and-paste job too.
I can’t set the position of the list when using this in C# assemblies. It doesn’t seem to be reading the position attributes of the component. Any ideas?
What exactly about setting the position is failing – what kind of error are you getting? Does your component compile?
Is it possible you haven’t assigned the GrasshopperDocument and Component variables? You need to do this if you use these variables outside of the C# component in Grasshopper. See here.
I am trying to instantiate the list at the same time as the component (i.e. Component has a list connected to it when it is created). Everything works, but the position is always relative to top left corner of the canvas (rather than the corner the component)
Hmm… I have done something similar without a problem. The component obviously needs to be fully instantiated so that it has a position, before you then try to create a value list. Where have you added the list instantiation code? I put it within the ‘solve instance’, then added a boolean that checked whether the value list had already been added (thus avoiding the ‘solve instance’ being called indefinitely). If you’re still at a loss, do you want to share some code?
Thanks for the quick replies.
Here is my test code:
GH_Document GrasshopperDocument;
IGH_Component Component;
public CustomCell()
: base(“CustomCell”, “Nickname”,
“Description”,
“IntraLattice2”, “Frame”)
{
}
protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
{
pManager.AddBooleanParameter(“just”, “a”, “test”, GH_ParamAccess.item, true);
}
protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
{
}
protected override void SolveInstance(IGH_DataAccess DA)
{
Component = this;
GrasshopperDocument = this.OnPingDocument();
//instantiate new value list
var vallist = new Grasshopper.Kernel.Special.GH_ValueList();
vallist.ListMode = Grasshopper.Kernel.Special.GH_ValueListMode.Cycle;
vallist.CreateAttributes();
//customise value list position
int inputcount = Component.Params.Input[1].SourceCount;
float xCoord = (float)Component.Params.Input[1].Attributes.Bounds.X;
float yCoord = (float)Component.Params.Input[1].Attributes.Bounds.Y;
PointF cornerPt = new PointF(xCoord, yCoord);
vallist.Attributes.Pivot = cornerPt;
//populate value list with our own data
vallist.ListItems.Clear();
var item1 = new Grasshopper.Kernel.Special.GH_ValueListItem(“choice 1”, “0”);
var item2 = new Grasshopper.Kernel.Special.GH_ValueListItem(“choice 2”, “1”);
var item3 = new Grasshopper.Kernel.Special.GH_ValueListItem(“choice 3”, “2”);
vallist.ListItems.Add(item1);
vallist.ListItems.Add(item2);
vallist.ListItems.Add(item3);
//Until now, the slider is a hypothetical object.
// This command makes it ‘real’ and adds it to the canvas.
GrasshopperDocument.AddObject(vallist, false);
//Connect the new slider to this component
Component.Params.Input[1].AddSource(vallist);
}
Hi Aidan, I think I see the issue. You have added one input. This first input is actually called Input[0], not Input[1]. When you reference Input[1], you are referencing an input that doesn’t exist, this is why it might return position of (0,0). Try changing your Input[1] to Input[0]. Does this help?
Hey James, I did a quick cleanup of my code before posting it and removed most of the inputs – sorry about that. The issue still isn’t solved.
Been having a go now, and yes, I’m struggling to position the list relative to the position of the input. For some reason, the input pivot value is being populated on component instantiation, but relative to (0,0) it seems. After the first calculation it is updated correctly. I couldn’t force an update of input pivot, so the best solution I found is instead to position your value list relative to the component position instead of the input position (something like Component.Attributes.Pivot.X). If you know the size of the component, the index, and the spacing between inputs, you can probably calculate a good-enough position.