Command With A Window

Hello,
I’m am trying to add a custom RhinoCommon plugin command that opens a window for the user to set some parameters and then upon pressing confirm, some Rhino objects are created and the command returns.

I am using Eto for the UI. Initially, I used an Eto.Form.Form object. However, when I call form.Show() from within the Rhino command, the thread continues to run and the command returns immediately. Any changes to the document done by the form object are not available to the ‘Undo’ that Rhino registers for the command.

So I changed the form object to an Eto.Forms.Dialog object so that I can open a modal dialog which blocks the calling thread and ran into a different problem that I cannot figure out. The window exposes a button which asks the user to select some models using a Rhino.Input.Custom.GetObject object. The GetObject ends up running twice. It behaves differently form the dialog than from the form but I am not sure why.

Attached is a plugin demonstrating these two situations, the form and the dialog. If possible, I would like to know how to properly handle this situation with both a Form and Dialog.

For the form, how do I safely block the thread until the form is closed?

var form = new CommandForm();
form.Show();
RhinoApp.WriteLine("form.Show(), thread continues and command returns too early");
return Result.Success;

For the dialog, why does this GetObject code behave differently when called from a modal dialog than from a form?

IsEnabled = false;
Minimize();

var go = new GetObject();
go.SetCommandPrompt("Select the models");
if (go.GetMultiple(1, 0) == GetResult.Object)
{
    foreach (var obj in go.Objects())
    {
         RhinoApp.WriteLine($"{obj.ObjectId}");
    }
}

IsEnabled = true;
BringToFront();

CommandWithWindow.zip (94.3 KB)

Hi @jakemurphy0118,

Have a look at this sample and see if it answers any questions.

SampleCsEtoSemiModalDialog.cs

– Dale

Hi Dale,

Thank you for pointing me there. I figured it out.

A Dialog seems to be the best way to block the command thread so that it only returns when the dialog is closed.
Any methods on the Dialog that require user input should be handled as below in order to work as expected:

button.Click += (s, e) => this.PushPickButton((s2, e2) => actionRequiringRhinoGetCalls())

I suppose PushPickButton is doing some work before and after the event in order to ensure the modal dialog behaves as expected.