This MiniBroker lesson shows how to access child objects from the root object using C# and .Net. In addition, we will use the proprety inspector component of .Net to change some properties. This example builds upon lesson 1.
Collections
All IRemotePremiseObject objects can have a collection of child objects. Thus you can find and manipulate the children or even more nested objects. For this lesson we will use only the most basic way of iterating through the collection of child objects.
The main way to iterate though the child objects is to use the children property of IRemotePremiseObject. This property directly exposes the collection. A collection of IRemotePremiseObject is exposed via the IRemotePremiseObjectCollection. The interface exposes the following a property called Count and several methods. The Count property can be used to find out how many objects are in the collection. Their are several methods the only ones of importances are Item, Add, and Remove. Item returns the object at a given position. Essentially the collection is a zero based array. Thus the valid indexes are 0 to Count - 1. Add and Remove methods add and remove IRemotePremiseObjects from the collection. The collection is also setup to have an Enumerator method so you can use the foreach syntax. Thus we iterate through the collection using either a for loop or for each enumerator. One thing to note is that the enumeration has one annoying feature. It iterates one past the actual count and thus the last item in the foreach loop is null. I do not know if that is a Premise feature or a Microsoft COM Interop feature. So, I have learned to just use the for loop rather than rely on foreach.
To actually load the tree view we need to add the children of the root object to the tree view (See the code below). This is accomplished by creating a method to loop through the children of a IRemotePremiseObject adding them to a TreeNode. Finally, change the form load event to use the new method.
private void Form1_Load(object sender, System.EventArgs e)
{
root = miniBroker.Connect("LocalHost", null, null);
PremiseObjectTree.Nodes.Add(BuildNode(root));
}
private TreeNode BuildNode(IRemotePremiseObject parentNode)
{
TreeNode result = new TreeNode(parentNode.DisplayName);
for(int loop=0; loop < parentNode.children.Count; loop++)
{
result.Nodes.Add(BuildNode(parentNode.children.Item(loop)));
}
return result;
}
Inspecting IRemotePremiseObject
Now that we have a tree view of premise objects it would be nice to inspect each object. One little know component that comes with VS.Net is a property inspector. This component is literally the property inspector that is used by VS.Net to change properties and by default is disabled. To have it show up in your tool box you will need to do the following:
- Bring up your form in the form designer tab
- Bring up the tool box using for example View|Tool Box
- Right click on a tool box component and select the menu option Add/Remove Items...
- When he Customize Toolbox dialog comes find and check the PropertyGrid .Net Framework Component
- Click Ok and the PropertyGrid component should now show up in your ToolBox Windows Forms category of components
This great little component automatically finds the exposed properties of .Net objects. To use this component simply drop it onto the ObjectView panel and rename it to PremisePropertyGrid. Any object property that is read and write can be changed. The change will actually be reflected in HCS (former Sys). Add the following line of code to the load method and viola you can see the exposed properties. Unfortunately their are not many. In the next lesson we will write some code to display and manipulate Premise properties that are not directly exposed!
PremisePropertyGrid.SelectedObject = root;
Selecting Objects
Our last task is hooking up selection of an object in the tree view to view it's properties in the property grid. To accomplish this we do the following:
- Figure out which IRemotePremiseObject to fetch
- Fetch the IRemotePremiseObject
- Set the selected object property of the property grid to the IRemotePremiseObject
First question you might have is how do you fetch the IRemotePremiseObject. One of the methods available to you in IRemotePremiseObject interface is GetObject. This method returns an IRemotePremiseObject based on its relative path, absolute path, or id. The path consists of the name of the parent object followed by a /. So for example to find the path of Home you would take the root whose name is sys:/ append a / and then the name of Home which is Home. This gives you sys://Home for a path. If you look at what we are storing in the Treeview you will notice that it is the DisplayName and not any of the items we need. Oops! So we can not use our current Tree view implementation.
The easiest way to handle this is to change what we store in the tree view from DisplayName to Name. Now we only figure out the path by traversing the node selected up to the root building a path. Once we have the path we can use this to fetch the object using the root object and the path we constructed. This gives us the following code is the complete listing include the code for the AfterSelect event of the tree view.
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using Premise;
namespace PremiseClient
{
///
/// Summary description for Form1.
///
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.TreeView PremiseObjectTree;
private System.Windows.Forms.Splitter splitter1;
private System.Windows.Forms.Panel ObjectView;
private ISYSMiniBroker miniBroker = new SYSMiniBrokerClass();
private IRemotePremiseObject root = null;
private System.Windows.Forms.PropertyGrid PremisePropertyGrid;
///
/// Required designer variable.
///
private System.ComponentModel.Container components = null;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
///
/// Clean up any resources being used.
///
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.PremiseObjectTree = new System.Windows.Forms.TreeView();
this.splitter1 = new System.Windows.Forms.Splitter();
this.ObjectView = new System.Windows.Forms.Panel();
this.PremisePropertyGrid = new System.Windows.Forms.PropertyGrid();
this.ObjectView.SuspendLayout();
this.SuspendLayout();
//
// PremiseObjectTree
//
this.PremiseObjectTree.Dock = System.Windows.Forms.DockStyle.Left;
this.PremiseObjectTree.ImageIndex = -1;
this.PremiseObjectTree.Location = new System.Drawing.Point(0, 0);
this.PremiseObjectTree.Name = "PremiseObjectTree";
this.PremiseObjectTree.SelectedImageIndex = -1;
this.PremiseObjectTree.Size = new System.Drawing.Size(121, 266);
this.PremiseObjectTree.TabIndex = 0;
this.PremiseObjectTree.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.PremiseObjectTree_AfterSelect);
//
// splitter1
//
this.splitter1.Location = new System.Drawing.Point(121, 0);
this.splitter1.Name = "splitter1";
this.splitter1.Size = new System.Drawing.Size(3, 266);
this.splitter1.TabIndex = 1;
this.splitter1.TabStop = false;
//
// ObjectView
//
this.ObjectView.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.ObjectView.Controls.Add(this.PremisePropertyGrid);
this.ObjectView.Dock = System.Windows.Forms.DockStyle.Fill;
this.ObjectView.Location = new System.Drawing.Point(124, 0);
this.ObjectView.Name = "ObjectView";
this.ObjectView.Size = new System.Drawing.Size(168, 266);
this.ObjectView.TabIndex = 2;
//
// PremisePropertyGrid
//
this.PremisePropertyGrid.CommandsVisibleIfAvailable = true;
this.PremisePropertyGrid.Dock = System.Windows.Forms.DockStyle.Fill;
this.PremisePropertyGrid.LargeButtons = false;
this.PremisePropertyGrid.LineColor = System.Drawing.SystemColors.ScrollBar;
this.PremisePropertyGrid.Location = new System.Drawing.Point(0, 0);
this.PremisePropertyGrid.Name = "PremisePropertyGrid";
this.PremisePropertyGrid.Size = new System.Drawing.Size(164, 262);
this.PremisePropertyGrid.TabIndex = 0;
this.PremisePropertyGrid.Text = "Premise Object";
this.PremisePropertyGrid.ViewBackColor = System.Drawing.SystemColors.Window;
this.PremisePropertyGrid.ViewForeColor = System.Drawing.SystemColors.WindowText;
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.ObjectView);
this.Controls.Add(this.splitter1);
this.Controls.Add(this.PremiseObjectTree);
this.Name = "Form1";
this.Text = "Premise Objects";
this.Load += new System.EventHandler(this.Form1_Load);
this.ObjectView.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
///
/// The main entry point for the application.
///
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void Form1_Load(object sender, System.EventArgs e)
{
root = miniBroker.Connect("LocalHost", null, null);
PremiseObjectTree.Nodes.Add(BuildNode(root));
PremisePropertyGrid.SelectedObject = root;
}
private TreeNode BuildNode(IRemotePremiseObject parentNode)
{
TreeNode result = new TreeNode(parentNode.Name);
for(int loop=0; loop < parentNode.children.Count; loop++)
{
result.Nodes.Add(BuildNode(parentNode.children.Item(loop)));
}
return result;
}
private void PremiseObjectTree_AfterSelect(object sender, System.Windows.Forms.TreeViewEventArgs e)
{
// Step 1 - Build the path to the object
TreeNode currentNode = e.Node;
string pathName = currentNode.Text;
if (string.Equals(currentNode.Text, root.Name))
{
pathName = "sys:/";
}
while (currentNode.Parent != null)
{
currentNode = currentNode.Parent;
if (string.Equals(currentNode.Text, root.Name))
{
pathName = "sys://" + pathName;
break;
}
else
{
pathName = currentNode.Text + "/" + pathName;
}
}
// Step 2 - Retrieve the object
IRemotePremiseObject selectedPremiseObject;
if (string.Equals(pathName, root.Path))
{
selectedPremiseObject = root;
}
else
{
selectedPremiseObject = root.GetObject(pathName);
}
// Step 3 - Set the PropertyGrid to the retieved object
PremisePropertyGrid.SelectedObject = selectedPremiseObject;
}
}
}
Play around with the object and see what you get. Next lesson we will focus on properties by looking at how we can cause all of the properties to show up in the property grid.