WPF GUI Example

I am currently working on a Rhino plugin that will need to have a UI that can be opened and closed. From what I have seen, WPF seems like a great way to build the UI, but I can not figure out how to incorporate those into the plugin. I saw from a post here that people are using WPF with Rhino and I was wondering if anyone could shed a little light on the topic for me.

http://forum.mcneel.com/t/can-rhinocommon-be-used-with-wpf/12/7

Do anyone have a simple example how a WPF window can be used with RhinoCommon?

Thanks in advance,

Ryan Gathmann

It depends if you want that window to be inside a rhino panel or not. For the panel case, refer to the post that you quoted above. In case of a “normal” window that does not have the Rhino Panel functionality, it is quite simple. All you need to do is use the WIndowInteropHelper to set the parent of your window to the Rhino main window:

Window my = new MyWindow();
new System.Windows.Interop.WindowInteropHelper(my).Owner = Rhino.RhinoApp.MainWindowHandle();
bool? result = my.ShowDialog();

The code above will show the window as a dialog and execution will move on after the window is closed - that means that the window stays on top of Rhino, and you can’t interact with Rhino. If you want to interact with Rhino, then use the code below:

my.Show();

In that case the window stays open until it is closed manually by the user, and the execution moves on after the statement.

3 Likes

This seems like what I am looking for. So, do i create a “Windows Form”, “User Control (WPF)”, or the “User Control”? I created a user control class called UserControl1 which inherits System.Windows.Controls.UserControl.

If I use the following code:
Window my = new UserControl1();
new System.Windows.Interop.WindowInteropHelper(my).Owner = Rhino.RhinoApp.MainWindowHandle();
bool? result = my.ShowDialog();

I get an error that says “Cant convert type UserControl1() into System.Windows.Window.” I am close, I just cant put my finger on it.

Thanks for everyones help and patience!

UserControl and Form is not what you want. UserControl (WPF) is not a standalone thing, but can be placed inside a WPF window.

You need to create a WPF window. This typically consists of a XAML file and a XAML.CS file.

You may want to read some more on WPF, for example on http://www.wpf-tutorial.com/ - specifically http://www.wpf-tutorial.com/getting-started/hello-wpf/ which shows how to create a window.

Menno,

Perfect thanks! I thought that was the issue but I couldn’t put my finger on it! I will post an example back here once I finish mine. I can usually stumble, I mean navigate my way through this stuff. Every once in a while and I just need to push on the right direction.

Do I not need a [System.STAThread] attribute on the Window? see http://stackoverflow.com/questions/1293402/why-does-wpf-require-a-stathread-attribute-to-be-applied-to-the-main-method

Nope - I don’t have that anywhere in our code base.

Hi @menno, thank you for this hint. It works well for me except for this:
I have a wpf user control with a button, inside a wpf window and a method that is executed on button click. The method adds some points to the document. It executes in both of the cases that you mention, but I am not able to undo it in Rhino anymore when I use

my.Show();

…to display the wpf window. The undo command undoes previous actions but it just ignores the points that were created by the method. Please note that everything works fine when

bool? result = my.ShowDialog();

…is used. It also works properly when the method is invoked via command line command.

Did you experience something like this before?

It is because your command finishes before the points are added when you use my.Show(). In that case you use a modeless dialog, whereas my.ShowDialog() uses a modal dialog. The difference is that the modal dialog will halt the execution inside your command until the dialog is closed.

The automatic undo system only works if you are inside a command. When using the modeless dialog, it does not work because you are outside the command.

Fortunately, you can get it to work by issuing the following statements:

RhinoDoc.ActiveDoc.StartUndoRecord();

RhinoDoc.ActiveDoc.BeginUndoRecord();
// modify the document, e.g. by adding points
RhinoDoc.ActiveDoc.EndUndoRecord();
2 Likes

Thank you very much. I’ve got it working properly now.

For others who might have the same problem:
It seems that the method is called RhinoDoc.ActiveDoc.BeginUndoRecord instead of RhinoDoc.ActiveDoc.StartUndoRecord.

The following worked for me:

public static Result MethodName(RhinoDoc doc, RunMode mode)
{
    uint undoRecord = doc.BeginUndoRecord("Start recording because of modeless dialog");
    // modify the document, e.g. by adding points
    doc.EndUndoRecord(undoRecord);
    return Result.Success;
}

new link to that post

Hi @menno,

Have not been this year at MARIN yet just was talking to few of your colleagues during SMM.

I am struggling with WPF here and not sure about WPF Window and WPF User Control.
The only one compoment I can add in VS under WPF is User Control (WPF).
Then I need to make a new instance of this control under RunCommand but it doesn’t pop up after New statement.

Actually do I need both UserControl and Window or only window is enough?

What is wrong? Can you guide?
Maybe you have a very short example?

Thanks,
Dmitriy

Hi,

Solved it by replacing type of UserControl to Window type (not provided by VS by default).
Also added Suystem.Xaml as a Reference.

Thanks,
Dmitriy

1 Like