Grasshopper

algorithmic modeling for Rhino

Calling DA.SetData(index, someName) outside of SolveInstance()

My question is - is there a way to call DA.SetData(index, someName) outside of SolveInstance? 

I have two methods within my main class, and that is AppendAdditionalMenuItems() and Menu_MyCustomItemClicked().


public override void AppendAdditionalMenuItems(ToolStripDropDown menu)
{
    base.AppendAdditionalMenuItems(menu);
    for (int i = 0; i < _firstList.Count; i++) {
        ToolStripMenuItem item = Menu_AppendItem(menu, _firstList[i], new                EventHandler(Menu_MyCustomItemClicked));
        item.Tag = i;
    }
}

private void Menu_MyCustomItemClicked(object sender, EventArgs e)
{
    ToolStripMenuItem item = sender as ToolStripMenuItem;
    int index = (int) item.Tag;
    _textBox = newList.FirstList[index];
    _outputStr = newList.SecondList[index];
}

I would like to set _outputStr from the Menu_MyCustomItemClicked(..) as my DA.SetData(..).

If I have DA.SetData() in my SolveInstance(), the first time the component is initialized, the string is blank, and it would cause my component to crash. Only after I manually run the component by triggering SolveInstance() to run again, do I get an output. 

Thanks!

Views: 679

Replies to This Discussion

That won't even compile, let alone work....

Menu_MyCustomItemClicked is clearly an event handler method. It thus needs to have the same signature as the event that it will be associated with, which -in this case- is Windows.Forms.ToolstripMenuItem.ItemClicked.

This is a .NET framework type and thus can't possibly know about the IGH_DataAccess type which is declared inside Grasshopper.dll. You cannot change the signature of an event handler without breaking the building process.

That aside, it is not possible to use IGH_DataAccess anywhere outside of SolveInstance(). Although you could technically insert data into output parameters outside the SolveInstance method, nobody will be able to figure out that you just changed the state and thus nobody will react to this new data.

If you want to change the data in a parameter then you must always trigger a new solution, during which you can insert your new data. So if you want to output some data based on which menu item a user clicked, the approach is:

  1. Handle the menu click event.
  2. Store some information so that you know what to do when the next solution comes around.
  3. Expire the component you're in so Grasshopper knows it is supposed to call SolveInstance on it.
  4. Trigger a new solution.
  5. Assign data to an output inside the SolveInstance() call that is triggered by this next solution.

Or, in code:

private string _localData = "DefaultData";

private void Menu_MyCustomItemClicked(object sender, EventArgs e)
{

  _localData = "MyCustomData";

  this.ExpireSolution(true);

}

protected override void SolveInstance(IGH_DataAccess DA)

{

  .....

  DA.SetData(0, _localData);

  .....

}

This approach should work, but it doesn't record an undo-event for clicking on the menu item. That takes additional code.

--

David Rutten

david@mcneel.com

All 5 items in my list are key. Leave out one and it won't work.

ExpireSolution(true) will expire the current object and all objects that in any way, shape or form depend on it. When it's done expiring, it will trigger a new solution, which in turn will recompute all the expired objects.

--

David Rutten

david@mcneel.com

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