Building a ProcessBook Docking Window with AF UI Controls

Blog Post created by dng on Jun 12, 2015

PI ProcessBook 2014 introduces a new AF Display Builder add-in that provides visualization to the AF hierarchy (see KB01122 for more information). The AF Display Builder allows users to easily explore PI AF elements and attributes as well as create symbols in PI ProcessBook. Recently, I was assisting a customer in building a PI ProcessBook docking window that displays the AF hierarchy. When users double-click on any element, the .pdi file associated with the element will be opened. I figure I will share this application here in case someone is looking to build a docking window for other purposes.


Part I of the blog post will show how to add some simple AF UI controls to a docking window in PI ProcessBook, while Part II will show how to modify the controls to open a .pdi file when an element is double-clicked.



Part I: Building a PI ProcessBook Docking Window with some AF UI Controls


Using the PI ProcessBook Add-In Templates


We provide VB.NET and C# templates for creating PI ProcessBook 3.x add-ins. These templates are available for download in the Tech Support Download Center. Since we are developing a docking window in C#, after downloading the templates, unzip and place the AddInPBDockWin_CS file in %USERPROFILE%\Documents\Visual Studio 2013\Templates\ProjectTemplates\Visual C# folder.


In Visual Studio 2013, create a new project and select the AddInPBDockWin_CS template:



Investigating the Docking Window Add-In Template


Let’s briefly investigate the docking window add-in project that we have just created from the template. For detailed information, please refer to the document “PI ProcesBook AddIn Templates for VS2008.doc” that comes with the template download.



The Connect class contains IDTExtensibility2 methods that all PI ProcessBook add-ins must implement. The two main methods that can be changed are:

  1. OnConnection
    • Specifies the load behavior when PI ProcessBook initializes the add-in.
  2. OnDisconnection
    • Specifies any cleanup needed when PI ProcessBook terminates the add-in.



This file contains the registry keys that PI ProcessBook uses to locate and initialize add-ins. While we are here, let’s edit the “FriendlyName” and “Description” field. Also, make sure that the registry path is correct (see the "extra" section below for more information).



Adding References to PI AF SDK and AF UI


Let’s add some references so we can access objects from the AF Database. In addition, we will make use of some ready-made controls available from the AF UI so we don’t have to reinvent the wheel.

  • AF SDK (from %pihome%\AF\PublicAssemblies\4.0\OSIsoft.AFSDK.dll)
  • AF UI (from %pihome%\AF\PublicAssemblies\4.0\OSIsoft.AF.UI.dll)

Since we are adding the .NET 4 version of the PI AF SDK and AF UI to the project, please ensure that the project is targeting .NET framework 4.5.



Adding the AF UI to a .NET User Control


We will next add a .NET user control and put some AF UI components in it. (Thanks to Steve Pilon’s post which gave many useful guidelines!)


1.     Right-click the PB_DockWin_AFTreeView project and add a user control. We’ll name it AFTreeControl.cs:



2.     In the design mode, resize the user control. We will then add 3 AF UI controls:

    • PISystemPicker: to allow user select and connect to an AF server
    • AFDatabasePicker: to allow user select and connect to a database in the AF server selected
    • AFTreeView: to display the AF element hierarchy


     For more information about AF UI components, refer to the AF User Interface Library Reference located at %pihome%\help\AFUIRef.chm.


     Modify the PISystem picker and AFDatabasePicker to remove unneeded controls. E.g.:



     The resulting user control will look something like this:



3.     Open the code behind the user control and make the user control visible to COM:


using System.Runtime.InteropServices;


namespace PB_DockWin_AFTreeView {     [ComVisible(true)]     public partial class AFTreeControl : UserControl     {



Adding functionality to the AF UI Controls


Let’s add code to our user control (AFTreeContol.cs) to allow us to populate the AFTreeView with the element hierarchy when an AF Server and AF Database is selected.


To begin, add using directives to the referenced AF SDK and AF UI:


using OSIsoft.AF; using OSIsoft.AF.UI;


We would like the AFDatabasePicker (named afDbPicker) to populate the list of databases whenever an AF server is selected from the PISystemPicker (named afPicker) control.


// Initialize the AF UI Controls public AFTreeControl() {     InitializeComponent();     afDbPicker.SystemPicker = afPicker; }


Next, we need populate the AFTreeView when users select/change the AF Database using AFDatabasePicker. We will add code to react to the SelectionChange event:

  • Click on the AFDatabasePickerControl and select Events under the Properties Window.
  • Double-click on SelectionChange:



Visual Studio will automatically populates code needed to handle this event. Back in the User Controls code, we see that afDbPicker_SectionChange has been added. Add the following code to get the elements to display in the AFTreeView (named afTreeView):


// Change the elements in the TreeView to the selected AF system and AF Database private void afDbPicker_SelectionChange(object sender, SelectionChangeEventArgs e) {     afTreeView.AFRoot = null;     AFDatabase myDatabase = afDbPicker.AFDatabase;     if (myDatabase != null && myDatabase.Elements != null)         afTreeView.AFRoot = myDatabase.Elements; }


Now, our control should display the AF element hierarchy after an AF server and database has been selected.



Displaying the User Control in PI ProcessBook


The last step would be to ask the docking window add-in to load our user control.


Let’s clean up the default label added as an example in the docking window template:

  • Remove the label control and the associated variable m_strAddInName
  • Change the name of the docking window to “AFTreeView Docking Window”
  • Add our user control (AFTreeControl) to the view in the docking window


The edited OnConnection method looks like the following:


public void OnConnection(object Application, Extensibility.ext_ConnectMode ConnectMode, object AddInInst, ref System.Array custom) {     try     {         m_theApp = (PBObjLib.Application)Application;          #region docking window          m_dockWindow = m_theApp.DockWindows.Add(PBObjLib.pbDockWindowType.pbTypeSingleViewWindow, "AFTreeView Docking Window", PBObjLib.pbDockPosition.pbDockLeft, false);          if (m_dockWindow != null)         {             m_dockWindow.Visible = true;              //ensure the tree view is fully visible             m_dockWindow.Width = 250;              //create a view in the docking window to contain the control             PBObjLib.PBControlView ctrlView = (PBObjLib.PBControlView)m_dockWindow.Views.Add(PBObjLib.pbViewType.pbControlViewType);              AFTreeControl treeControl = (AFTreeControl)ctrlView.CreateControl("PB_DockWin_AFTreeView.AFTreeControl");         }          #endregion      }     catch (Exception ex)     {         MessageBox.Show("Exception in OnConnection=" + ex.Message);     } }



Finally, we are ready to test! Note that the Debug configuration specify the start action as opening PI ProcessBook. Make sure to change the hard-coded path to reflect the actual location of the PI ProcessBook executable on your machine.



Clicking Debug will register the add-in in the registry (remember AddReg.reg?) and launch PI ProcessBook. The docking window should now be loaded automatically!




Part II: Additional Functionality


We have successfully added a AFTreeView in a PI ProcessBook docking window! We are ready to add some custom functionality!


As I mentioned in the beginning of this blog post, the goal of this application is to open up a .pdi file when user double-click on any element. To do that, we will parse the path of the element by accessing the node that has been double-clicked. If a .pdi file with the same name already exists, the file will be opened; if not, a new file will be opened.


To open up a display at a double-click event, the user control needs to know about the PI ProcessBook application.


// The processBook application public PBObjLib.Application app; 


We can then set the ProcessBook Application in the OnConnection method during initialization:


AFTreeControl treeControl = (AFTreeControl)ctrlView.CreateControl("PB_DockWin_AFTreeView.AFTreeControl"); treeControl.app = m_theApp;


(By the way, this is by no means perfect. Please feel free to comment/improve upon this!)



Let’s add code to react to a NodeMouseDoubleClick event: (make sure to first create an event handler for the event as described above for the SectionChange event for the AFDatabasePicker)


using System.IO;


// Open a new display when the node is double-clicked private void afTreeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e) {      // Parse element path to get the name of the element     string[] path = e.Node.FullPath.Split('\\');     string filePath = String.Format("C:\\Dev Support\\VBA in PB\\{0}.pdi", path[path.Length - 1]);       // If the pdi exists, open the file     if (File.Exists(filePath))     {         app.Displays.Open(filePath, false);     }      // If pdi doesn't exist, add a dislpay with the name of the element     else     {         app.Displays.Add(path[path.Length - 1]);     } }



Rebuild the project and test the new functionality in PI ProcessBook!



Extra: A Few Tips about Deployment


Note that PI ProcessBook reads the list of add-ins from the registry at

  • HKLM\SOFTWARE\Wow6432Node\PISystem\PI – ProcessBook\Addins, or
  • HKLM\SOFTWARE\Software\PISystem\PI – ProcessBook\Addins


depending on the bitness. It is important to modify the AddinReg.reg file so that the registry keys are added in the correct location.


To modify the load/unload behavior, you can open up Add-In Manager in PI ProcessBook (Tools > Add-In Manager) and modify the default loading properties for your add-in:



Finally, if you have finished development and would like to deploy your add-in on a client machine, please refer to KB00592.





The full project is in the GitHub repository pb-dockwin-aftreeview. Feedback and comments are always welcomed!