WPF has simply the most powerful templating and visual engine that is available at the moment for designing your UI. A requirement came up in a project that required a watermarked textbox for displaying some contextual help.
With WPF this becomes trivial. So lets first create a control that extends TextBox to add our watermark text property.
public class TextBoxWithHelp : TextBox
{
public string HelpText
{
get {return (string)GetValue(HelpTextProperty); }
set { SetValue(HelpTextProperty, value); }
}
public static readonly DependencyProperty HelpTextProperty =
DependencyProperty.Register("HelpText",
typeof(string),
typeof(TextBoxWithHelp),
new PropertyMetadata(String.Empty));
}
This code creates us a control that functions exactly the same as a TextBox but allows us a DependencyProperty we can bind some watermark to. So now can we use this control and style it as needed. And this becomes a pretty simple task. What we will do is take the default style of a TextBox and add an additional element and some additional triggers. For brevity, I’ve omitted all the TemplateBindings which are not required for this example.
<Style x:Key="TextBoxWithHelp"
TargetType="{x:Type local:TextBoxWithHelp}">
<Setter
Property="Template">
<Setter.Value>
<ControlTemplate
TargetType="{x:Type local:TextBoxWithHelp}">
<Microsoft_Windows_Themes:ListBoxChrome
x:Name="Bd"
SnapsToDevicePixels="true" >
<Grid>
<ScrollViewer
x:Name="PART_ContentHost" />
<TextBlock
x:Name="PART_HelpTextElement"
Text="{TemplateBinding HelpText}"
Visibility="Collapsed"/>
</Grid>
</Microsoft_Windows_Themes:ListBoxChrome>
<ControlTemplate.Triggers>
<Trigger
Property="Text"
Value="">
<Setter
TargetName="PART_HelpTextElement"
Property="Visibility"
Value="Visible"/>
</Trigger>
<Trigger
Property="Text"
Value="{x:Null}">
<Setter
TargetName="PART_HelpTextElement"
Property="Visibility"
Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
What we have changed in the base TextBox style is the addition of the “PART_HelpTextElement” TextBlock. This is the element that the watermark will sit in and is collapsed by default. In the control template triggers collection, you’ll notice that the moment that the control’s Text Property is “” or null, the watermark TextBlock’s visibility property will be set to Visible and the watermark will become visible.
This is a simple solution for a problem that occurs quite frequently. Because of the power of WPF, you are able to style the watermark in any fashion you require.
Michael Lonnon has just provided us with the latest MSDN half-day Roadshow events that are taking place in February 2009. Its a sneak peak before the official announcement goes out on Wednesday, so head on over to sign up now.
Find out about all MSDN events
MSDN: Catch up with Microsoft Rich Client Technologies for 2008
Date: 10 February 2009
Location: London
MSDN: Catch up with Microsoft Rich Client Technologies for 2008
Date: 12 February 2009
Location: Birmingham
MSDN: Catch up with Microsoft Rich Client Technologies for 2008
Date: 24 February 2009
Location: Edinburgh
TBC
MSDN: Catch up with Microsoft Rich Client Technologies for 2008
Date: 26 February 2009
Location: Manchester
As promised, I've uploaded my code and slides from last night's talk at Nxtgen Cambridge. Many thanks to Chris Hay for allowing me to spout my MVVM pattern talk at the guys. I hope it was enjoyable and you managed to learn something from the evening. I'm always open to feedback, so if you have any, please forward it on
Code Download
Slides Download
Just a reminder to all you WPF and Silverlight developers out there that I'm presenting at Nxtgen Cambridge on the MVVM pattern. We will look at how to design a WPF application and spend quite a lot of time deep in code. I have one more space in the car leaving Windsor if anyone needs a lift, so sign up below to let them know you're coming!
http://www.nxtgenug.net/ViewEvent.aspx?EventID=158
At the Vista Squad event that happens on the 15th of October I'll be co-presenting on UAC with Aaron Parker. He'll be doing the majority of the talk and I'll be presenting on why devs (or at least just me) develop in admin mode.
Hopefully we'll have some interesting comment from our members. We have a slightly smaller crowd which generally means a more personal touch so I'm really looking forward to this.
Its not too late to sign up, so head on over to the sign up page to get your name in. :)
Yes, finally we’ll have an RTM product to build with. I cannot wait to finally have a stable API and something we can push to customers.
More info at the press release with news that the RTM will be available to download on the 14th. No news on developer tools and Expression Blend also being released at the same time?
I’ve been busy with a Silverlight project where our models are all implementing INotifyPropertyChanged. I’m not a big fan of INotifyPropertyChanged because of the need to raise the event with the property name as a string. This can lead to numerous spelling mistakes and broken code.
So the easiest solution to this is to unit test. But the unit tests are all the same and very monotonous to write. Attach an event handler, set property Assert that the property was changed properly.
Lets change this today to something more automatic. I’ve written a class that allows you to pass an object in that implements INotifyPropertyChanged and it will test all the properties for you.
1: public class PropertyTester<T>
2: where T : INotifyPropertyChanged
3: {
4: List<string> _propertyChangedProperties = new List<string>();
5:
6: public void AssertCorrectProperties
7: (T item, Action<T> propertySetter, string message)
8: {
9: //Subscribe to the event
10: item.PropertyChanged +=
11: new PropertyChangedEventHandler(Type_PropertyChanged);
12: //Call the action to set the items
13: propertySetter(item);
14:
15: //Get all the property names that have public set methods
16: //that we should compare
17: //this obviously makes the assumption that all
18: //properties accessible sets call NotifyPropertyChanged
19: var propertyNames =
20: from property in
21: item.GetType().GetProperties(
22: BindingFlags.Instance | BindingFlags.Public)
23: where property.CanWrite
24: select property.Name;
25:
26: CollectionAssert.AreEquivalent
27: (propertyNames.ToList(),
28: _propertyChangedProperties,
29: message);
30: }
31:
32: private void Type_PropertyChanged
33: (object sender, PropertyChangedEventArgs e)
34: {
35: //Not the best, but without a HashSet<T> in Silverlight,
36: //I'm happier with a list and
37: //a Contains over a Dictionary<T,K> for testing purposes
38: if (!_propertyChangedProperties.Contains(e.PropertyName))
39: {
40: _propertyChangedProperties.Add(e.PropertyName);
41: }
42: }
43: }
The first thing you notice is that to create the PropertyTester, your generic type must implement INotifyPropertyChanged. There is an assumption that this class makes and this is that all your publicly settable properties actually do call NotifyPropertyChanged().
Lets run through this then. In the AssertCorrectProperties method, you pass in an instance to test and an Action<T> that we will call to set the properties and fire NotifyPropertyChanged. The method subscribes to the NotifyPropertyChanged event and calls the action. In the event handler all we are doing is creating a list and adding each of the property names to the list. The method then enumerates over all the properties of T to find the publicly settable properties and compares this list to make sure it is equivalent to the property names that were fired.
As long as the properties are equivalent then we have a successful pass of the test. I’ve attached some code below which shows what a potential test could look like.
1: public class Pet : INotifyPropertyChanged
2: {
3: public event PropertyChangedEventHandler PropertyChanged;
4:
5: private string _name;
6: /// <summary>
7: /// Gets or sets the back text
8: /// </summary>
9: public string Name
10: {
11: get { return _name; }
12: internal set
13: {
14: if (_name != value)
15: {
16: _name = value;
17: NotifyPropertyChanged("Name");
18: }
19: }
20: }
21:
22: private DateTime _dateOfBirth;
23: public DateTime DateOfBirth
24: {
25: get { return _dateOfBirth; }
26: internal set
27: {
28: if (_dateOfBirth != value)
29: {
30: _dateOfBirth = value;
31: NotifyPropertyChanged("DateOfBirth");
32: }
33: }
34: }
35:
36: protected void NotifyPropertyChanged(string PropertyName)
37: {
38: OnNotifyPropertyChanged(PropertyName);
39: }
40:
41: protected virtual void OnNotifyPropertyChanged(
42: string PropertyName)
43: {
44: if (this.PropertyChanged != null)
45: {
46: this.PropertyChanged(this,
47: new PropertyChangedEventArgs(PropertyName));
48: }
49: }
50: }
51:
52: [TestClass]
53: public class PetTest
54: {
55: [TestMethod]
56: public void TestProperties()
57: {
58: Pet dog = new Pet
59: {
60: Name = "Fido",
61: DateOfBirth = DateTime.Now
62: };
63: PropertyTester<Pet> tester = new PropertyTester<Pet>();
64: Action<Pet> propertySetter = new Action<Pet>(p =>
65: {
66: p.DateOfBirth = DateTime.MaxValue;
67: p.Name = "Fred";
68: });
69: tester.AssertCorrectProperties(
70: dog,
71: propertySetter,
72: "Properties are not set correctly.");
73: }
74: }
I love Reflector. Nothing beats reading the source code of a closed library that you're having issues with to determine what is the cause. Or reading the .NET framework to better understand what is going on.
I had the issue this evening of helping my dad with a .NET app that would crash on importing a file. I opened the app in Reflector and saw this massive try block around the code, doing a MessageBox.Show(ex.Message) on the caught exception. Since I couldn't easily see the error in the code, and the try catch block meant that we lost the stack trace something more drastic needed to be done.
I headed on over to Reflexil's site. Reflexil is an addin for Reflector that allows you modify the IL and then save back the patched exe to disk. Its damn amazing.
Immediately I changed the IL to instead of calling the Message getter, to call the exception's StackTrace getter and voila, I have a message box showing me more detailed information.
Be warned though, that you do have to change the IL, not C# or VB.NET, otherwise an invaluable tool for this real edge cases.
Karen Corby has an awesome set of 4 blog posts on Visual State Manager. She discusses what it does, shows us how to use states, parts and transitions and is a very informative set of posts.
Part 1
Part 2
Part 3
Part 4
Just posted up with the videos available for some of them. Follow the link to watch them. Some of them only have the slides available with audio but altogether a great resource.
Remix Sessions

From Tim Leung:
"We’re holding our VBUG annual conference at Thames Valley Park on the 4th/5th November. It’s £399 for non VBUG members and our international speakers include Ken Getz and Roy Osherove. The topics covered will include:
• Data-Driven ASP.NET AJAX
• Silverlight for mobile
• Create managed code for Office 2007 in Visual Studio 2008
• ASP.NET 4.0
• Team Foundation Server
To find out more, we’ve produced a PDF brochure which you can see here: http://www.vbug.com/uploaded/documents/conference-2008/VBUG%20Winter%20Conference%202008.pdf
Here’s the link for registration:
http://www.vbug.com/Events/October-2008/THE-VBUG-NET-ANNUAL-CONFERENCE-2008.aspx"
Sounds like a pretty awesome day out. Hope to see you there!