Creating a Visual Studio 2005 Tools/Options Page

This draft walkthrough guides you through the steps of creating two Tools/Options pages. It will become available in the RTM release of Visual Studio Industry Program (VSIP) 2005. But I thought some of you might want to test it now. Of course this is provided in an as is, use at your own risk condition.

 

The simple page uses a property grid to examine and set properties, while the custom page provides its own user interface. The managed package framework (MPF) supports both scenarios, with very little additional code.

 

The MPF provides two classes to help you create Tools/Options pages. You create a VSPackage to provide a container for these pages by subclassing the T:Microsoft.VisualStudio.Shell.Package class. You create the Tools/Options pages themselves by deriving from the T:Microsoft.VisualStudio.Shell.DialogPage class.

 

In this walkthrough, you create the Tools/Options pages and use them to display and change options. You retrieve the option values from the hosting VSPackage. You retrieve them again from another VSPackage via automation.

· Creating a Tools/Options Property Grid.

· Creating a Tools/Options Custom Page.

· Accessing Options from the Hosting VSPackage.

· Accessing Options using Automation.

   Creating a Tools/Options Grid Page

In this section, you create a simple Tools/Options property grid using the Visual Studio Integration Package wizard. You use this grid to display and change the value of a property.

 

To create a Tools/Options property grid

1. Create a new Visual Studio Integration Package project named, for example, MyToolsOptions. For more information on creating a managed VSPackage, see How to: Create a VSPackage Using the Visual Studio Integration Package Wizard topic in the Visual Studio beta two doc set.

The Package Wizard runs.

2. In the Select a Programming Language page, select Visual C# .

3. In the Select VSPackage Options page, select Menu Command.

4. In the Command Options page, change the Command Name to "Get internal option". Click Finish.

The wizard creates the managed project MyToolsOptions and the unmanaged resource-only project MyToolsOptionsUI.

5. Open the file MyToolsOptions/VsPkg.cs and add a new class to the namespace, just before the MyToolsOptions class. Derive the new class from MSVSIP.DialogPage. Use the Tools/Create Guid tool with registry format to copy and paste a new Guid into the code, removing the curlique brackets. The code should look something like this (your Guid will differ):

namespace Vsip.MyToolsOptions

{

    [Guid("FFF9BEA5-CA30-49e7-A72E-FE220A29E6FD")]

   public class OptionPageGrid : MSVSIP.DialogPage

    {

    }

6. Add a System.Runtime.InteropServices.ClassInterfaceAttribute to the OptionPageGrid class:

[ClassInterface(ClassInterfaceType.AutoDual)]

[Guid("FFF9BEA5-CA30-49e7-A72E-FE220A29E6FD")]

public class OptionPageGrid : MSVSIP.DialogPage

This creates a COM dual interface that lets Visual Studio automation access the public members of the class programmatically via M:Microsoft.VisualStudio.Shell.Package.GetAutomationObject(System.String).

7. Add a T:Microsoft.VisualStudio.Shell.ProvideOptionPageAttribute to the MyToolsOptions class, giving it the CategoryName "My Category", the PageName "My Grid Page", and setting SupportAutomation to true:

[MSVSIP.ProvideOptionPage(typeof(OptionPageGrid), "My Category", "My Grid Page", 0, 0, true)]

[Guid("b3125df0-8db0-408f-8a3f-25e7aac2a2c0")]

public sealed class MyToolsPackage : MSVSIP.Package

Note You can localize the category and page name by assigning resource IDs to the attribute properties CategoryResourceID and PageNameResourceID, respectively.

8. Add this line to the using statements at the beginning of the file to make the following step easier to read:

using System.ComponentModel;

9. Add the OptionInteger property to the OptionPageGrid class. Use the System.ComponentModel.CategoryAttribute to give it the category "My Options" and System.ComponentModel.DescriptionAttribute to give it the description "My integer option":

public class OptionPageGrid : MSVSIP.DialogPage

{

   private int _optionInt = 256;

    [Category("My Options")]

    [Description("My integer option")]

   public int OptionInteger

    {

      get { return _optionInt; }

      set { _optionInt = value; }

    }

}

Note The default implementation of T:Microsoft.VisualStudio.Shell.DialogPage supports properties that have appropriate converters, or else are structures or arrays that can be expanded into properties that have appropriate converters. For a list of converters, see the System.ComponentModel namespace. See also the OptionsPage (a topic in the Visual Studio 2005 beta two) sample, which manages int, string, and System.Drawing.Size properties.

10. Build and launch the project in debug mode by pressing the keyboard shortcut, F5. This launches Visual Studio Exp.

Note Both versions of Visual Studio are open at this time.

11. From Visual Studio Exp, select the Tools/Options menu item.The Options dialog opens.

12. In the tree view in the left pane, select My Category/My Grid Page.The options grid appears in the right pane. The property category is "My Options", and the property name is OptionInteger. The property description "My integer option" appears at the bottom of the pane.

Change the value of OptionInteger from its initial value 256 to something else. Click OK, then reopen My Grid Page. You can see that the new value has persisted.

 

   Creating a Tools/Options Custom Page

In this section, you create a Tools/Options page with a custom UI. You use this page to display and change the value of a property.

 

To create a Tools/Options custom page

13. Close Visual Studio Exp.

14. From the file MyToolsOptions/VsPkg.cs, add the OptionPageCustom class to the namespace, just before the OptionPageGrid class. Derive the new class from MSVSIP.DialogPage. Use the Tools/Create Guid tool with registry format to copy and paste a new Guid into the code, removing the curlique brackets. Add the string property OptionString. The code should look something like this (your Guid will differ):

namespace Vsip.MyToolsOptions

{

    [ClassInterface(ClassInterfaceType.AutoDual)]

    [Guid("1D9ECCF3-5D2F-4112-9B25-264596873DC9")]

   public class OptionPageCustom : MSVSIP.DialogPage

    {

      private string _optionString = "alpha";

      public string OptionString

       {

         get { return _optionString; }

         set { _optionString = value; }

       }

    }

}

15. Add a T:Microsoft.VisualStudio.Shell.ProvideOptionPageAttribute to the MyToolsOptions class, giving it the CategoryName "My Category", the PageName "My Custom Page", and setting SupportAutomation to true:

[MSVSIP.ProvideOptionPage(typeof(OptionPageCustom), "My Category", "My Custom Page", 0, 0, true)]

[Guid("b3125df0-8db0-408f-8a3f-25e7aac2a2c0")]

public sealed class MyToolsPackage : MSVSIP.Package

16. Right-click the MyToolOptions project node and select Add/New Item.

17. Add a user control named MyUserControl to the project.The user control opens in design view.

18. From the toolbox, add a TextBox to the user control. In the Properties window, select the Events tab (lightning bolt icon). In the Focus section, double-click the Leave event.

The code editor opens to show the new event handler.

19. Add a public OptionsPage field, an Initialize method, and the body of the event handler to the MyUserControl class. Your code should look like this:

public partial class MyUserControl : UserControl

{

   public MyUserControl()

   {

      InitializeComponent();

   }

   public OptionPageCustom OptionsPage;

   public void Initialize()

    {

      textBox1.Text = OptionsPage.OptionString;

    }

private void textBox1_Leave(object sender, EventArgs e)

{

      OptionsPage.OptionString = textBox1.Text;

}

}

The OptionsPage field holds a reference to the parent OptionPageCustom instance. The Initialize method displays OptionString in the TextBox, and the event handler writes the current value of the TextBox to the OptionString when focus leaves the TextBox.

20. In the VsPkg file, add an override for the OptionPageCustom.Window property to create, initialize, and return an instance of MyUserControl. Your code should look like this:

public string OptionString

{

   get { return _optionString; }

   set { _optionString = value; }

}

[Browsable(false), DesignerSerializationVisibility(

   DesignerSerializationVisibility.Hidden)]

protected override IWin32Window Window

{

   get

    {

      MyUserControl page = new MyUserControl();

      page.OptionsPage = this;

      page.Initialize();

      return page;

    }

}

21. Build and launch the project in debug mode by pressing the keyboard shortcut, F5. This launches Visual Studio Exp.

Note Both versions of Visual Studio are open at this time.

22. From Visual Studio Exp, select the Tools/Options menu item.The Options dialog opens.

23. In the tree view in the left pane, select My Category/My Custom Page.The options grid appears in the right pane. The property category is "My Options", and the property name is OptionString.

Change the value of OptionString from its initial value "alpha" to something else. Click OK, then reopen My Custom Page. You can see that the new value has persisted.

 

   Accessing Options from the Hosting VSPackage

In this section, you obtain the value of an option from the VSPackage that hosts the associated Tools/Options page. The same technique can be used to obtain the value of any public property.

To access an option from the hosting VSPackage

24. Close Visual Studio Exp.

25. Add this line to the using statements at the beginning of MyToolsOptions/VsPkg.cs to make the following step easier to read::

using System.Windows.Forms;

26. Replace the body of the MyToolsOptions.MenuItemCallback method with the following lines:

private void MenuItemCallback(object sender, EventArgs e)

{

   OptionPageGrid page = (OptionPageGrid) GetDialogPage(typeof(OptionPageGrid));

   MessageBox.Show(

      string.Format("OptionInteger: {0}", page.OptionInteger));

}

This code calls M:Microsoft.VisualStudio.Shell.Package.GetDialogPage(System.Type) to create or retrieve an OptionPageGrid instance. OptionPageGrid in turn invokes M:Microsoft.VisualStudio.Shell.DialogPage.LoadSettingsFromStorage to load its options, which are public properties.

27. Build and launch the project in debug mode by pressing the keyboard shortcut, F5. This launches Visual Studio Exp.

Note Both versions of Visual Studio are open at this time.

28. Select the Tools/Get internal option menu item. This opens a message box and displays the current value of OptionInteger.

 

   Accessing Options using Automation

In this section, you obtain the value of an option from any VSPackage or Add-in using automation. The same technique can be used to obtain the value of any public property.

To access an option using automation

29. Close Visual Studio Exp.

30. Right-click the MyToolsOptions solution node in the Solution Explorer and add a new Visual Studio Integration Package project named, for example, AnotherPackage. For more information on creating a managed VSPackage, see How to: Create a VSPackage Using the Visual Studio Integration Package Wizard.

The Package Wizard runs.

31. In the Select a Programming Language page, select Visual C# .

32. In the Select VSPackage Options page, select Menu Command.

33. In the Command Options page, change the Command Name to "Get external option". Click Finish.

The wizard creates the managed project AnotherPackage and the unmanaged resource-only project AnotherPackageUI.

34. Right-click the AnotherPackage project node and select Set as StartUp Project.

35. Right-click the References node of the AnotherPackage project and select Add Reference.

36. From the .COM tab, select Microsoft Development Environment 8.0, which typically references C:\Program Files\Common Files\Microsoft Shared\MSEnv\dte80.olb.

37. Add these lines to the using statements at the beginning of AnotherPackage/VsPkg.cs to make the following step easier to read::

using EnvDTE;

using System.Windows.Forms;

38. Replace the body of the AnotherPackage.MenuItemCallback method with the following lines:

private void MenuItemCallback(object sender, EventArgs e)

{

   DTE dte = (DTE)GetService(typeof(DTE));

   EnvDTE.Properties props =

      dte.get_Properties("My Category", "My Grid Page");

   int n = (int) props.Item("OptionInteger").Value;

   MessageBox.Show("OptionInteger: " + n);

}

This code calls a service to get the T:EnvDTE.DTE object, the root object of the Visual Studio automation model. P:EnvDTE._DTE.Properties(System.String,System.String) returns the properties collection for My Category.MyGridPage, which includes all public properties. The Item method selects OptionInteger from the collection.

39. Build and launch the project in debug mode by pressing the keyboard shortcut, F5. This launches Visual Studio Exp.

Note Both versions of Visual Studio are open at this time.

40. Select the Tools/Get external option menu item. This opens a message box and displays the current value of OptionInteger.

Enjoy, Martin Tracy, Programmer Writer

Important note: This material is provided in an 'as is' condition so that you might evaluate it for your own use at your own risk. You agree that by providing comments, suggestions, or other feedback related to our products, technology or services to the individuals listed above, you allow Microsoft, at its option, to use your feedback in our products, technology, and services without any obligation to you. Due to the volume of e-mails we receive, Microsoft, including the individual listed above, may not be able respond to your e-mail. Cancelled vs Canceled