algorithmic modeling for Rhino
Hi Michael,
this is definitely possible. If you want to do something like the Scripting Components, then you'll need to:
1) Create a System.Windows.Forms.Form using the Visual Studio form designer or create a form through code.
2) Add a public function to your component that displays this form, I recommend you use form.ShowDialog() for now to avoid weird conditions with non-modal forms.
3) Override the method Menu_AppendCustomComponentItems() on your Component and add an extra menu item that will show the form (i.e. when clicked, it will call the function defined in step [2].
4) Create a new class and derive it from Grasshopper.Kernel.Attributes.GH_ComponentAttributes. (if you don't want to offer double-click functionality, you can skip steps 4 to 6)
5) Override the RespondToMouseDoubleClick() method on the new attributes and also call the function defined in step [2]
6) Override the CreateAttributes() method on your Component class and construct an instance of the custom attributes defined in step [4] instead.
7) Once you've shown the form and the user has clicked OK, you need to assign values and invalidate the Component, then start a new Solution.
Here's some code:
Public Class MySpecialComponentAttributes
Inherits GH_ComponentAttributes
Public Sub New(ByVal comp As MySpecialComponent)
MyBase.New(comp)
End Sub
Public Overrides Function RespondToMouseDoubleClick( _
ByVal sender As GH_Canvas, _
ByVal e As GH_CanvasMouseEvent) As GH_ObjectResponse
DirectCast(Me.Owner, MySpecialComponent).DisplayForm()
Return Canvas.GH_ObjectResponse.Handled
End Function
End Class
Public Class MySpecialComponent
Inherits GH_Component
.....
.....
Protected Overrides Sub Menu_AppendCustomComponentItems( _
ByVal iMenu As ToolStripDropDown)
Menu_AppendGenericMenuItem(iMenu, "Set Values", AddressOf Menu_SetValues)
End Sub
Private Sub Menu_SetValues(ByVal sender As Object, ByVal e As EventArgs)
DisplayForm()
End Sub
Public Sub DisplayForm()
Dim frm As New MySpecialForm()
Grasshopper.GUI.GH_WindowsFormUtil.CenterFormOnCursor(frm, True)
If (frm.ShowDialog() = DialogResult.OK) Then
'Harvest values from form and assign them to local variables
Me.ExpireSolution(True)
End If
End Sub
End Class
--
David Rutten
david@mcneel.com
Turku, Finland
Hi David,
I had compiled a test gha in VisualStudio (C#) and was able to run the Form via new dropdown menu item, but the doubleclick response didn't work to run the form. Would you please give some hint what I am missing here, thank you so much.
Happy New Year,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using Grasshopper;
using Grasshopper.GUI;
using Grasshopper.Kernel;
using Grasshopper.Plugin;
using test_gh.Properties;
using Grasshopper.GUI.Canvas;
using Grasshopper.Kernel.Attributes;
using GH_IO.Serialization;
namespace test_gh
{
    public class Class1: GH_Component
    {
        public Class1() : base("@test", "@test", "@test is a collection of parametric modeling tool", "@test", "") 
        {
            //sa = new SettingsComponentAttributes(Class1);
        }
        public override Guid ComponentGuid
        {
            get { return new Guid("B60B6812-C9DB-4D4B-BAEF-170534B846DE"); }
        }
        public override void AppendAdditionalMenuItems(ToolStripDropDown menu)
        {
            base.AppendAdditionalMenuItems(menu);
            Menu_AppendSeparator(menu);
            Menu_AppendItem(menu, "Learn More", Menu_LearnMore);
        }
        private void Menu_LearnMore(Object sender, EventArgs e)
        {
            DisplayForm();
            //this.ExpirePreview(true);
            //this.ExpireSolution(true);
        }
        public override GH_Exposure Exposure
        {
            //expose the object in the section on the toolbar
            get { return GH_Exposure.primary; }
        }
        protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
        {
        }
        protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
        {
            
        }
        protected override Bitmap Icon
        {
            get
            {
                //return Resources.Attrct_it;
                return Resources._it;
            }
        }
        protected override void SolveInstance(IGH_DataAccess DA)
        {
           
        }
        public void DisplayForm()
        {
            MySpecialForm frm = new MySpecialForm();
            Grasshopper.GUI.GH_WindowsFormUtil.CenterFormOnCursor(frm, true);
            if ((frm.ShowDialog() == DialogResult.OK))
            {
                //Harvest values from form and assign them to local variables
                this.ExpireSolution(true);
            }
        }
        public class MySpecialComponentAttributes : GH_ComponentAttributes
        {
            public MySpecialComponentAttributes(IGH_Component Class1) : base(Class1) { }
            public override GH_ObjectResponse RespondToMouseDoubleClick(GH_Canvas sender, GH_CanvasMouseEvent e)
            {
                ((Class1)Owner).DisplayForm();
                return GH_ObjectResponse.Handled;
            }
        }
    }
}
Did you override CreateAttributes on Class1 and set a new MySpecialComponentAttributes instance to m_attributes?
--
David Rutten
david@mcneel.com
Thank you David,
No I haven't of course ... I looked at again to .chm for custom attribute section, proposed something like below,but what should be the constructor ?
        public override void CreateAttributes()
        {
            //m_attributes = new MySpecialComponentAttributes(Class1); 
            m_attributes = new MySpecialComponentAttributes(???);
        }
public override void CreateAttributes()
{
  m_attributes = new MySpecialComponentAttributes(this);
}
--
David Rutten
david@mcneel.com
Thank you so much, happy new year
Hi David,
I am trying to recreate Elcin's code to prototype some code for custom checklists and number sliders as I described here: http://www.grasshopper3d.com/forum/topics/creating-custom-number-sl...
I created my own Specialform within the same namespace as the rest the code, it is simply a windows form with one button.
Unfortunately whenever I try to run the method DisplayMethod I get the Exception
Do you have any pointers as to what is going on? I am pretty lost.
How come you're using Rhino_DotNET.dll? That is the old SDK which has been deprecated and replaced by RhinoCommon.dll
David,
Thanks by doing a clean build I fixed the problem which was quite weird.
Cheers,
Anton
Welcome to
Grasshopper
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
    © 2025               Created by Scott Davidson.             
    Powered by
    