Custom Property Pages


An Outlook add-in can add a custom property page to the Properties dialog box for a folder or to Outlook's Options dialog box. We walk through how this is done using a VSTO Outlook add-in. First, create a VSTO Outlook add-in project in VSTO by following the instructions in Chapter 24, "Creating Outlook Add-Ins with VSTO."

After you create a basic VSTO Outlook add-in project, you need to add a user control project item to the project. A user control is a special kind of Windows Forms control that is useful for inserting into another window. To add a user control to your project, click the project node in Solution Explorer and then choose Add User Control from the Project menu. When you double-click the newly added user control project item, you will see the user control designer, shown in Figure 9.8. You can resize the user control using the drag handle in the bottom-right corner. Resize it to about 410 x 355 pixels, which is the size of a property page in Outlook. With the user control resized, use the controls toolbox (choose Toolbox from the View menu if it is not already showing) to add controls to your user control surface. In Figure 9.8, we have added several check boxes, radio buttons, and buttons to the user control surface.

Figure 9.8. The user control designer.


To use this user control as a custom property page, we must make some modifications to the code behind it. Right-click the user control project item in Solution Explorer, and choose View Code. First, we must implement an interface required by Outlook called PropertyPage. The PropertyPage interface has two methods and a property. The Apply method is called on our PropertyPage implementation when the user clicks the Apply button in the Outlook Options or Folder Properties dialog box. The GetPageInfo method gets a help filename and help context so that you can provide help for your custom property page. The Dirty property is a Boolean property that you can use to let Outlook know whether the user has changed any settings in your custom property page. When Dirty returns true, Outlook knows to enable the Apply button in the dialog box so that the user can apply changes made in the custom property page.

Second, we must add a property that Outlook will call to get the caption for the property page tab. This property must be marked with a DispId attribute that Outlook uses to identify which property will return the caption for the property page tab. The name of the property does not matter as long as it returns a String; in Listing 9.1, we name the property PageCaption.

Listing 9.1 shows what your class should look like after you have made these modifications. Because user controls use the partial class feature in Visual Studio, all the code that is specific to how many buttons or controls you added should not show up in this file, but in the other hidden part of the partial class. Note that the code uses the System.Runtime.InteropServices namespace for the DispID attribute on the Caption property. The code also declares a constant called captionDispID that is set to the ID Outlook expects will be associated with the Caption property.

Listing 9.1. First Version of the Modified User Control Class

Imports Outlook = Microsoft.Office.Interop.Outlook Imports System.Runtime.InteropServices Public Class UserControl1   Implements Outlook.PropertyPage   Const captionDispID As Integer = -518   Private isDirty As Boolean = False   Public Sub Apply() Implements _     Microsoft.Office.Interop.Outlook.PropertyPage.Apply     MsgBox("The user clicked the Apply button.")   End Sub   Public ReadOnly Property Dirty() As Boolean _     Implements Outlook.PropertyPage.Dirty     Get       Return isDirty     End Get   End Property   Public Sub GetPageInfo(ByRef HelpFile As String, _     ByRef HelpContext As Integer) _     Implements Outlook.PropertyPage.GetPageInfo   End Sub   <DispId(captionDispID)> _   Public ReadOnly Property PageCaption() As String     Get       Return "Test Page"     End Get   End Property End Class 


With the user control created, two event handlers must be added. The first event handler is for the Application object's OptionsPagesAdd event. This event is raised when Outlook is ready to add custom property pages to the Outlook Options dialog box, which is shown when the user chooses Options from the Tools menu. The event handler is passed a pages parameter of type PropertyPages that has an Add method that can be used to add a user control as a custom property page.

The second event handler is for the NameSpace object's OptionsPages Add event. This event is raised when Outlook is ready to add custom property pages when a Properties dialog box for a folder is displayed. The Properties dialog box for a folder is shown when the user right-clicks a folder and chooses Properties from the pop-up menu. The event handler is passed a pages parameter of type PropertyPages that has an Add method that can be used to add a user control as a custom property page. The event handler is also passed a folder parameter of type MAPIFolder that specifies the folder for which the Properties dialog box will be shown.

Listing 9.2 shows an implementation of a VSTO ThisApplication class that handles these two events. In the event handlers for the Application object's OptionsPagesAdd event and the NameSpace object's OptionsPagesAdd event, an instance of the user control in Listing 9.1 is created and passed as the first parameter to the PropertyPages.Add method. The second property is passed an empty string because the caption for the custom property page is retrieved by Outlook calling the PageCaption property on the user control that has been attributed with a DispID known to Outlook.

Listing 9.2. A VSTO Outlook Add-In That Handles the OptionsPagesAdd Event on Application and Namespace

Imports Microsoft.VisualStudio.Tools.Applications.Runtime Imports Outlook = Microsoft.Office.Interop.Outlook Public Class ThisApplication   Private nameSpace1 As Outlook.NameSpace   Private Sub ThisApplication_Startup(ByVal sender As Object, _     ByVal e As System.EventArgs) Handles Me.Startup     AddHandler Me.OptionsPagesAdd, _       AddressOf ThisApplication_OptionsPagesAdd     nameSpace1 = Me.Session     AddHandler nameSpace1.OptionsPagesAdd, _       AddressOf NameSpace_OptionsPagesAdd   End Sub   Private Sub ThisApplication_OptionsPagesAdd( _     ByVal pages As Outlook.PropertyPages)     pages.Add(New UserControl1(), "")   End Sub   Private Sub NameSpace_OptionsPagesAdd( _     ByVal pages As Outlook.PropertyPages, _     ByVal folder As Outlook.MAPIFolder)      pages.Add(New UserControl1(), "")   End Sub End Class 


If you compile and run this VSTO add-in, you will get the result shown in Figure 9.9 when you show Outlook's Options dialog box and click the Test Page tab.

Figure 9.9. A custom property page added to Outlook's Options dialog box.


If you right-click a folder and choose Properties, you can also see that the custom property page is added to the folder's Properties dialog box, as shown in Figure 9.10.

Figure 9.10. A custom property page added to a folder's Properties dialog box.


If you play with these dialog boxes a bit, you will notice that the Apply button never gets enabled when you change the check boxes or radio buttons in the custom property page. Also note that the Apply method that was implemented as part of implementing the PropertyPage interface is never called. To fix this, the implementation of the user control is modified as shown in Listing 9.3 so that when a check box or radio button is changed, it changes the value of the class variable isDirty to true. In addition, the code notifies Outlook that the property page state has changed by connecting to Outlook's PropertyPageSite object. The code declares a propertyPageSite class member variable and sets it by calling the InitializePropertyPageSite method in the Load event handler. The Load event handler must use reflection to get the PropertyPageSite object.

With the PropertyPageSite connected, the code defines a method called SetIsDirty that changes the state of the isDirty variable and then calls Outlook's PropertyPageSite.OnStatusChange method. This notifies Outlook that it needs to call into the PropertyPage interface to get the new state of the custom property page. A complete implementation would detect any changes made to the property page that could change the dirty state and potentially detect when a change is undone and clear the dirty state back to false.

Finally, the code raises the CheckedChanged event of the first check box on the custom property page. When the changed state changes, the code calls SetIsDirty to set the dirty state to true and notifies Outlook that the state has changed.

Listing 9.3. Second Version of a User Control Class That Handles Dirty State Properly

Imports Outlook = Microsoft.Office.Interop.Outlook Imports System.Runtime.InteropServices <ComVisible(True)> _ Public Class UserControl1   Implements Outlook.PropertyPage   Const captionDispID As Integer = -518   Private isDirty As Boolean = False   Private propertyPageSite As Outlook.PropertyPageSite = Nothing   Public Sub Apply() Implements _     Microsoft.Office.Interop.Outlook.PropertyPage.Apply     MsgBox("The user clicked the Apply button.")   End Sub   Public ReadOnly Property Dirty() As Boolean _     Implements Outlook.PropertyPage.Dirty      Get        Return isDirty      End Get   End Property   Public Sub GetPageInfo(ByRef HelpFile As String, _     ByRef HelpContext As Integer) _     Implements Outlook.PropertyPage.GetPageInfo   End Sub   <DispId(captionDispID)> _   Public ReadOnly Property PageCaption() As String      Get       Return "Test Page"      End Get   End Property   Private Sub SetIsDirty(ByVal value As Boolean)     isDirty = value     propertyPageSite.OnStatusChange()   End Sub   Private Sub CheckBox1_CheckedChanged(ByVal sender As Object, _     ByVal e As System.EventArgs) Handles CheckBox1.CheckedChanged     SetIsDirty(True)   End Sub   Private Sub UserControl1_Load(ByVal sender As Object, _     ByVal e As System.EventArgs) Handles Me.Load     InitializePropertyPageSite()   End Sub   Private Sub InitializePropertyPageSite()     Dim windowsFormsStrongName As String = _      Type.GetType("System.Windows.Forms.Form"). _      Assembly.FullName.ToString()     Dim objType As Type = GetType(System.Windows.Forms.Form)     Dim windowsFormsStrongName As String = _      objType.Assembly.FullName.ToString()     Dim oleObjectType As Type = Type.GetType( _       System.Reflection.Assembly.CreateQualifiedName( _       windowsFormsStrongName, _       "System.Windows.Forms.UnsafeNativeMethods")). _       GetNestedType("IOleObject")     Dim getClientSiteMethodInfo As System.Reflection.MethodInfo     getClientSiteMethod Info = _       oleObjectType.GetMethod("GetClientSite")     propertyPageSite = CType(getClientSiteMethodInfo.Invoke( _       Me, Nothing), Outlook.PropertyPageSite)   End Sub End Class 


Now when you run the add-in and change the checked state of the first check box in the custom property page, the dirty state is changed, and Outlook's PropertyPageSite is notified. The result is that the Apply button is enabled. Clicking the Apply button invokes the test dialog box in Listing 9.3's implementation of the Apply method.




Visual Studio Tools for Office(c) Using Visual Basic 2005 with Excel, Word, Outlook, and InfoPath
Visual Studio Tools for Office: Using Visual Basic 2005 with Excel, Word, Outlook, and InfoPath
ISBN: 0321411757
EAN: 2147483647
Year: N/A
Pages: 221

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net