Grasshopper

algorithmic modeling for Rhino

Is it possilble to implement a Custom windows.forms window in a Grasshopper Component? And if it is can i Store inputdata within the Component instances ?i looked at the scripting Component... But i Found no hint.

Views: 2853

Replies to This Discussion

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

thx david thats cool...

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

Need to answer post.

Happy new year.

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.

Thanks 

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

RSS

About

Translate

Search

Photos

  • Add Photos
  • View All

Videos

  • Add Videos
  • View All

© 2024   Created by Scott Davidson.   Powered by

Badges  |  Report an Issue  |  Terms of Service