.comment-link {margin-left:.6em;}

I Hate Linux

Wednesday, January 09, 2008

WHS Dev Tip #14: ITabExtender, Part 3: Multiple-Tabs

Under the current tab model we are familiar with... the Home Server Console looks for a class named HomeServerTabExtender in a namespace based on the name of the assembly (ie HomeServerConsoleTab.MyTab.dll holds Microsoft.HomeServer.HomeServerConsoleTab.MyTab) for information on the display of a given Console add-in.

As simple as this system is, it is extremely limiting as it means that an assembly can only contain a single tab, which leads to multiple assemblies being required for a more complicated add-in that might require multiple tabs (such as in Settings), ITabExtender changes that.

Next

ITabExtender defines a read-only property named Next which returns another ITabExtender, enabling a programmer to create a linked-list of add-in tabs with remarkable ease.

Lets look back at the code sample from Monday of the extra properties and methods we get with ITabExtender over IConsoleTab:

public ITabExtender Next
{
   get { return null; }
}
 
public void Prepare()
{
   
}
 
public void Refresh()
{
   
}
 
public ITabStatus Status
{
   get { return null; }
}
 
public int TabOrdinal
{
   get { return 33; }
}

Right now Next is just returning null... in order to return something useful we first need to create another class that implements the ITabExtender interface, create an instance of it and return it. Unlike with the main class, this time though we can choose an arbitrary name and put it in any namespace we want:

public class ExtraConsoleTabClass : ITabExtender
{
   private IConsoleServices consoleServices;
   private MainTabUserControl tabControl;
 
   public ExtraConsoleTabClass(int width, int height, IConsoleServices consoleServices)
   {
      this.consoleServices = consoleServices;
 
      tabControl = new MainTabUserControl(width, height, consoleServices);
 
      //Additional setup code here
 
 
 
   }      
 
   #region ITabExtender Members
 
   public ITabExtender Next
   {
      get { return null; }
   }
 
   public void Prepare()
   {
      
   }
 
   public void Refresh()
   {
      
   }
 
   public ITabStatus Status
   {
      get { return null; }
   }
 
   public int TabOrdinal
   {
      get { return 34; }
   }
 
   #endregion
 
   #region IConsoleTab Members
 
   public bool GetHelp()
   {
      return false;
   }
 
   public Guid SettingsGuid
   {
      get { return Guid.NewGuid(); }
   }
 
   public Control TabControl
   {
      get { return tabControl; }
   }
 
   public Bitmap TabImage
   {
      get { return Properties.Resources.DefaultToolBarIcon; }
   }
 
   public string TabText
   {
      get { return "Extra Tab"; }
   }
 
   #endregion
}

Note: You are free to create your lower classes/tabs anyway you like, I prefer sticking to the same conventions and constructors as in the parent tab for simplicity.

At this point all we need to do is wire up the new ITabExtender with the one that will be automatically found by the Home Server Console... and in order to do this all we need to do is create an instance of the new class, store it some where and spit it back out when the Next property is read:

ExtraConsoleTabClass extraTab;
 
...
 
public HomeServerTabExtender(int width, int height, IConsoleServices consoleServices)
{
   this.consoleServices = consoleServices;
 
   tabControl = new MainTabUserControl(width, height, consoleServices);
 
   //Additional setup code here
 
   extraTab = new ExtraConsoleTabClass(width, height, consoleServices);
 
}
 
...
 
public ITabExtender Next
{
   get { return extraTab; }
}

And when it's all said and done (and loaded in the Home Server Console) we are greeted with our two tabs:

ITabExtender - Two Tabs

Because this method works just like a (read only) linked-list, we can do it almost indefinitely (provided we remember that the Home Server Console only supports a finite number of tabs):

ITabExtender - Six Tabs

A word of warning though... do not have an ITabExtender refer to itself... or have any kind of circular dependency in your tab set as it will run indefinitely and cause the Home Server Console to take quite a while to load as it waits for your add-in to fail.

Settings

Like so many of the other features of ITabExtender, the same functionality works with ISettingsExtender when used in the settings dialog:

ISettingsExtender x3

Sample

A sample add-in demonstrating everything discussed here will be part of the last post on Thursday.

Conclusion

ITabExtender and it's Next property enables programmers to easily define multiple tabs in a single assembly, offering the opportunity to visually break one large and complicated add-in into smaller and more manageable sub components that can each be represented by their own tab, keeping in mind the whole while that the Windows Home Server Console only supports a finite number of tabs.

Next Time

Tomorrow: Tab status

Note: The information in this post is based on undocumented and at times deduced information on Windows Home Server and is not officially supported or endorsed by Microsoft and could very easily be wrong or subject to change in future, so please take it and everything else said on this blog with a grain of salt and use with caution.

Labels:

0 Comments:

Post a Comment

<< Home