Grasshopper

algorithmic modeling for Rhino

C# class does not implement inherited abstract member?

Hi Guys,

 

I am trying to write a GH component (on visual studio C# express) that opens a  Windows File Dialog when being double clicked on (with a filter defining a specific acceptable file extension). So far I wrote the disfonctional code below thanks to this and this discussion as well as this tutorial (all within Giulio's VS wizzard).

I get the following errors on the third line:

Error 1 'myComponent.LoadSettings' does not implement inherited abstract member 'Grasshopper.Kernel.GH_Component.SolveInstance(Grasshopper.Kernel.IGH_DataAccess)'  

and

Error 2 'myComponent.LoadSettings' does not implement inherited abstract member 'Grasshopper.Kernel.GH_Component.RegisterOutputParams(Grasshopper.Kernel.GH_Component.GH_OutputParamManager)'  

I hope someone can help me solve this. My component still doesn't show up when I debug the code. Many thanks!

      namespace myComponent
       {
       public class LoadSettings : GH_Component
       {
        public LoadSettings()
            : base("LoadSettings", "LS",
                "Loading .ini",
                "Extra","")
        {
        }
  public override void CreateAttributes()
    {
      m_attributes = new HelperAttributes(this);
    }

  class HelperAttributes : GH_ComponentAttributes
    {
        LoadSettings a;
        public HelperAttributes(LoadSettings _a)
            : base(_a)
        {
            a = _a;
        }   
public override GH_ObjectResponse RespondToMouseDoubleClick(GH_Canvas sender, GH_CanvasMouseEvent e)
    {
    System.Windows.Forms.OpenFileDialog ofd = new  System.Windows.Forms.OpenFileDialog();
    ofd.Multiselect = true;
 
    ofd.Filter = "Data Sources (*.ini)|*.ini*|All Files|*.*";
    if (ofd.ShowDialog() == DialogResult.OK)

        {
        string[] filePath = ofd.FileNames;
        string[] safeFilePath = ofd.SafeFileNames;
        }
    return base.RespondToMouseDoubleClick(sender, e);
    }
    }
 
        public override Guid ComponentGuid
        {
            get { return new Guid("{02d35086-fddb-472d-8ce3-646cdfacf036}"); }
        }
    }
}


 

Views: 3720

Replies to This Discussion

Sorry,

I got rid of the errors by typing:

 protected override void SolveInstance(IGH_DataAccess DA)
        {}

and

protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
        {}

When you use Giulio's wizard, shouldn't it automatically instantiate those classes for you? did you delete them?

Hi Andrew,

You are right, I deleted the classes as I thought that I didn't need them which was wrong.

The code compiles with no errors and creates a GHA that works when being double clicked on but no data is being stored in the output parameter (the component just stays orange).

I think I should add a statement in the SolveInstance class to call the return value of the RespondToMouseDoubleClick() Method. Not sure how to approach this yet though...Any ideas?

SolveInstance is called on every solution, if you want to write data to an output parameter that comes from a window, you indeed need to store the data somewhere safe, after you display the window.

I find it easiest to put this stuff on the component itself, not the attributes (very rough code, it's past 1am):

public class SettingsComponentAttributes: GH_ComponentAttributes

{

   //implement constructor blah blah blah

  public override GH_ObjectResponse RespondToMouseDoubleClick(GH_Canvas sender, GH_CanvasMouseEvent e)

  {

    ((SettingsComponent)Owner).ShowSettingsGui();

    return handled;

  }

}

public class SettingsComponent: GH_Component

{

    public SettingsComponent():base(yadayadayada){}

    private SomeKindOfData m_settings;

    public override void CreateAttributes()

    {

      m_attributes = new SettingsComponentAttributes(this);

    }

    public void ShowSettingsGui()

    {

        //TODO: if you want this to be undoable, you need to add read/write support for settings as well.

        //Display whatever window you need to let the user specify settings:

        m_settings = SomeNewSettings;

    }

   protected override void SolveInstance(IGH_DataAccess DA)

   {

     if (m_settings == null)

     {

       AddRuntimeMessage(warning, "You must declare some valid settings");

       return;

     }

     DA.SetData(0, m_settings);

   }

}

--

David Rutten

david@mcneel.com

Poprad, Slovakia

Hi David,

Thanks so much for your reply!

Where is the 'handled' variable coming from in 'return handled'? VS is telling me that it not recognized in the current context. I ve changed the statement to 'e.Handled = true;' (after getting some help from Stack Overflow) but got another error:  'Grasshopper.GUI.GH_CanvasMouseEvent' does not contain a definition for 'Handled' and no extension method 'Handled' accepting a first argument of type 'Grasshopper.GUI.GH_CanvasMouseEvent' could be found

I hope that I translated the rest of the code correctly nevertheless:

namespace myComponent
{
    public class SettingsComponentAttributes : GH_ComponentAttributes
    {
        public override GH_ObjectResponse RespondToMouseDoubleClick(GH_Canvas sender, GH_CanvasMouseEvent e)
        {
            ((SettingsComponent)Owner).ShowSettingsGui();
            e.Handled = true;
        }
    }


    public class SettingsComponent : GH_Component
        {
        public SettingsComponent()
                : base("LoadSettings", "LoadSettings",
                    "Loading .ini",
                    "Extra", "") { }

       
                public override void CreateAttributes()
        {
            m_attributes = new SettingsComponentAttributes(this);
        }


        private string m_settings;
        public void ShowSettingsGui()
        {
            
            System.Windows.Forms.OpenFileDialog ofd = new System.Windows.Forms.OpenFileDialog();
            ofd.Multiselect = true;
            ofd.Filter = "Data Sources (*.ini)|*.ini*|All Files|*.*";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                string[] filePath = ofd.FileNames;
                string[] safeFilePath = ofd.SafeFileNames;
            }
           m_settings = Path.GetDirectoryName(ofd.FileName);
        }

        protected override void SolveInstance(IGH_DataAccess DA)
   {
     if (m_settings == null)
     {
       AddRuntimeMessage(warning, "You must declare some valid settings");
       return;
     }
     DA.SetData(0, m_settings);
   }

}
    }

That function is supposed to return a GH_ObjectResponse value. handled is just one of the possible values: GH_ObjectResponse.Handled

 

When you type "Return " in VS it should automatically suggest these, which is why I used the shorthand. You return handled to inform Grasshopper that it should not continue doing what it would normally do on a double click.

 

--

David Rutten

david@mcneel.com

Poprad, Slovakia

Thank you very much!

The GH_ObjectResponse.Handled works well.

 

I am now having troubles with the SettingsComponentAttributes statement below. It says that the class does not contain a constructor that takes 1 arguments

 

public override void CreateAttributes()
                {
                    m_attributes = new SettingsComponentAttributes(this);
                }

I have tried adding a constructor in the class itself but it did not help (bit confused on what's happening there):

public SettingsComponentAttributes(SettingsComponentAttributes obj)
{
}

Weirdly, the message disapears when removing the 'this' keyword :)

RSS

About

Translate

Search

Videos

  • Add Videos
  • View All

© 2024   Created by Scott Davidson.   Powered by

Badges  |  Report an Issue  |  Terms of Service