Q: How can I create my own list like what I see in the Home Server Console's Network Health dialog?
A: Another one of the custom ListBox (like) controls exposed by Windows Home Server is the MessageListBox control, the very control that is used to display network health messages as well as the installed and available add-ins:
Like so many other controls, in order to use it we need only drag an instance from the toolbox to our form or control in the designer... but it is here where the simplicity ends.
While called a ListBox... MessageListBox inherits from the Panel class and offers only a few extra enhancements over it... the most notable being the Items field which is the collection of MessageListBoxItem instances which correspond to the visual items we see.
In order to add new items to the list, it can be as simple as:
MessageListBoxItem redItem = new MessageListBoxItem(Color.Red);
MessageListBoxItem yellowItem = new MessageListBoxItem(Color.Yellow);
MessageListBoxItem greenItem = new MessageListBoxItem(Color.Green);
Which gives us the following:
Once we've created our items, we want to tweak them a bit through the use of the Title and Description properties which corresponds to the bold title text and body text respectively:
redItem.Title = "Big ole problem";
redItem.Description.Text = "Important information on the specifics of this error goes here.";
yellowItem.Title = "Minor issue";
yellowItem.Description.Text = "The world is going to end... just not today.";
greenItem.Title = "All is well";
greenItem.Description.Text = "Pay no attention to the man behind the curtain.";
Which brings us to this point:
And for good measure, lets add some eye candy with some existing icons:
redItem.Icon = CommonImages.StatusCritical24Icon;
yellowItem.Icon = CommonImages.StatusAtRisk24Icon;
greenItem.Icon = CommonImages.StatusHealthy24Icon;
to bring us to:
Each MessageListBoxItem comes with a button ready for us... all we need to do is set it's text to make it visible:
redItem.ActionButton.Text = "Fix Error";
Of course to make it truly useful, we also have to manually wire up an event handler and the code to do something with the event:
redItem.ActionButton.Click += new EventHandler(ActionButton_Click);
void ActionButton_Click(object sender, EventArgs e)
//Determine which button was clicked
Button b = sender as Button;
//Determine which MessageListBoxItem the button exists on
MessageListBoxItem mlbi = b.Parent as MessageListBoxItem;
//Do useful processing
//Remove specified MessageListBoxItem
Instead of using a button for a single action, we can use the built in CheckBox functionality to allow toggling of a setting.
Using the supplied CheckBox is similar to using the Button where we set the properties Text property and wire up and event handler... note that we are also required to set the CheckBox's Visible property to true:
yellowItem.CheckBox.Text = "Ignore this";
yellowItem.CheckBox.Visible = true;
yellowItem.CheckBox.CheckedChanged += new EventHandler(CheckBox_CheckedChanged);
Once wired up we can use the CheckBox very similar to how we used the ActionButton:
void CheckBox_CheckedChanged(object sender, EventArgs e)
CheckBox cb = sender as CheckBox;
MessageListBoxItem mlbi = cb.Parent as MessageListBoxItem;
//Do useful processing
mlbi.GradientColor = (Color)mlbi.Tag;
//Do useful processing
mlbi.GradientColor = Color.Gray;
Which brings us to:
Note the above example assumes that we are also storing the enabled color in the MessageListBoxItem's Tag property (as in the sample for this post).
Be aware that while you can use both the ActionButton and CheckBox... doing so isn't very advisable due to the way both controls are rendered together:
In order to set the description of the MessageListItem we have to set Description.Text instead of just Text is because Description is a LinkLabel which gives is more control than just displaying text... it allows us to define a specific area to be a clickable hyperlink.
To set that up, we need to modify or replace the LinkArea property of the Description property to specify where the link should begin and for how long it will as well as wire up an event handler:
greenItem.Description.Text = "Pay no attention to the man behind the curtain.\nClick here for more information";
//Link starts on 48th character and is 31 character long
greenItem.Description.LinkArea = new LinkArea(48, 31);
greenItem.Description.LinkClicked += new LinkLabelLinkClickedEventHandler(Description_LinkClicked);
void Description_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
//Do something based on link
Like so many other of the Windows Home Server Controls, MessageListBox is lacking in a few ways.
Aside from it's limited designer support, it does also suffer from a bit of an issue... choppy redrawing which most often occurs whenever a MessageListBoxItem is added or removed from the visible list.
Ideally after a MessageListBox is populated, its contents should not be altered while visible. While this is not a requirement, doing so will reduce the likelihood of the various sub controls used in each MessageListBoxItem from flashing about.
Putting it all together, again I've provided a pair of add-ins that show off the simplicity of MessageListBox and how we can use it visually:
MessageListBox provides a simple way to create a rich list of color coded messages for a user provided the drawing issues are understood and worked around.
I'm not sure yet... What would you like to see? I'd love to hear your ideas.
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.
Read the complete post at http://feeds.feedburner.com/~r/IHateLinux/~3/208991213/whs-developer-tip-12-messagelistbox.html