In the previous post, I showed you how easy is to add an options page to a VSPackage with the predefined (property grid) UI. Often, you need to add your custom UI instead of a property grid to provide a better user experience. For example, specifying a color with its textual name is not an excellent way, since you have names only for several dozen colors out of the 16 million available through RGB codes.

In this post, you will learn to create your custom options page UI. By default, you need to create Windows Forms custom controls to represent your page—thus, for the sake of simplicity, I will use this technology.

Instead of creating a new package, you carry on with the SimpleOptionsPagePackage sample you implemented in Part #6. First, you are going to create the custom UI to represent the same text settings that you applied in the previous post. Next, you will update the tool window to use the options page with the custom UI.

Creating the Options Page Class

Just as options pages with the default property grid UI, the ones that apply their custom UI derive from DialogPage. Create a new class, GreetingOptionsPage, and set up its properties similarly to GreetingsOptionsGrid:

Observe, now the TextColor property is a Color (System.Windows.Forms), and not a string.

Create a new Windows Forms Custom Control (Figure 1) with the Add New Item command; name it GreetingsControl.

Figure 1: Add a new Windows Forms User Control to the project

Edit the UI so that I would look like in Figure 2.

Figure 2: The UI of the custom options page

The custom control encapsulates three Label controls, a NumericUpDown, a Button, and a ColorDialog. If you are not familiar with editing Windows Forms Control, just copy this code into the GreetingsControl.Designer.cs file (a nested Solution Explorer node within GreetingsControl.cs):

With the View Code (F7) command, you can define the code behind the custom control. Type the following code for the GreetingsControl class:

The constructor binds the user control to its hosting options page so that it can initialize it and later, as the user changes settings, the new option values can be set.

Binding the Custom UI with the Options Page

Now, you can add the new options page to OptionsPagesPackage with the same ProvideOptionPage attribute used in Part #6:

Now, the package has two options pages (Figure 3). Although you have already created a new custom UI, it is not associated yet with GreetingsOptionsPage, so the UI still displays a property grid.

Figure 3: The new custom page—still with a property grid

To let the new UI appear in the Options dialog, override the Window property of GreetingsOptionsPage, as highlighted here:

The IWin32Windows interface (declared in the System.Windows.Forms namespace) represents an object that can return a window handle. By default, Window returns a handle to a user control that displays the property grid. By overriding it, we can provide a handle to a custom control instance, just as we do in this code. Evidently, we return a handle to the user control that represents the custom options page UI.

NOTE: You can host WPF User Controls in options pages, too, nonetheless it requires some additional hacking. See this article for more details.

When you run the package, the Experimental Instance shows the custom UI (Figure 4).

Figure 4: The options page with the custom UI

Updating the Tool Window

At the moment, we have two options pages, and the first is bound with GreetingToolWindow. Change the code of GreetingToolWindowControl to apply the settings in the new options page:

As the highlighted changes show, we need to convert colors from Windows Forms (System.Drawing.Color) to WPF (System.Windows.Media). When you run the package, the welcome message text properties change according to the custom options page settings. Nonetheless, you should close and display the tool window again to let the changes be applied.

Observing Options Changes

Visual Studio does not provide a mechanism to notify you about options page property changes, so you need to implement your notification pattern. Nonetheless, you can apply your favorite method. One possible solution is—I would not say, it is the best—to add a static event to GreetingsOptionsPage:

NOTE: I do not prefer static classes and events because they may cause difficulties when unit testing. I’d rather use some lightweight messaging, such as the one in the MVVM Light Toolkit.

Now, in GreetingToolWindowControl, you can handle the OptionsChanged event:

Where We Are

In this blog post, you have learned that you can create a custom options page with Windows Forms user controls—when you need a custom UI instead of the default property grid.

In the next post, you will learn a few things about the automation model in Visual Studio.

Leave a comment

Your email address will not be published. Required fields are marked *