Today I would like to conclude my little series about the Notification Pattern with (I guess at least for some of you) the most interesting part:
Today is all about displaying Notifications in the UI
This post will guide you through all the steps I took in order to achieve the
affect I demonstrated in the introduction post.
Last time I showed how I’m transfering
Notifications from the
into the logical WPF tree. If you’ve not read the previous posts, please
give them some minutes, because I’m not going to repeat a lot of them
today. You can find them
As always, a quick reminder:
What I’m showing is in this series is how I’ve implemented the Notification Pattern. I’m not claiming that it’s the only or the best way to do so. However, it’s the one that works very good for me.
How to get the red border effect
The red border has to be displayed when Notifications exists for a control. Technically
this means that the attached property
Notifications (which is defined
ValidationBehavior class I showed in the last post) is set to a
NotificationCollection. We can react to this by defining a
DataTrigger for this. In my own words I would describe a
An in XAML defined event handler with a related criteria. When the criteria is matched the DataTrigger gets executed. When it isn’t matched any more, the DataTrigger reverts the state of the element on which it’s defined to the state before it was executed.
Sounds usable for our purpose. Think about it, we only want to show the red border, when the
attached property is set to a non empty collection. If the property is
reset the border needs to disappear. The only difficulty with
DataTriggers we need to solve on our way is how to configure that
exactly in XAML.
DataTriggers can be easily set on primitives (such as
string, bool, etc.) or null, but there isn’t an out of the box way for
setting our criteria in XAML. However you can use a custom Converter for
converting our value to a primitive “switch”.
1 2 3 4 5 6 7 8 9 10 11 12 13
Using this converter we can define our DataTrigger in the Style for Controls like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
How to display Notifications in a Tooltip
Solving the Tooltip requirement was a bit more tricky (at least for me). It took me quite some time to figure out how to do this in WPF. The solution I’m going to show uses only XAML based code.
1. Integrating the Tooltip into the DataTrigger
We simply use our
DataTrigger to automatically set the tooltip of a
Control in case
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Now the UI looks really crappy. The tooltip is not recognizable as one.
2. Using a ControlTemplate to style the Tooltip
In order to shape the appearance of the tooltip we can use XAML Styles again.
You can change the whole visual appearance of a Control using Styles and
ControlTemplates. The template I defined consists mostly of a
Label (which provides the tooltips caption) and a
(which will later contain the Notification messages).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
Our UI now looks like this.
Not as crappy as before but we’re not finished yet, because we’re not
3. Define Databinding on the Tooltip
Defining the Databinding was probably the hardest step I had to take.
The problem is that you need to get the
NotificationCollection from the
Control the tooltip is displayed on. Being not a WPF pro figuring out
how to do this took quite some time. Anyway, in order to get the
Notification there isn’t much you need to do. The trick is to bind
against the property
PlacementTarget on the
ToolTip class itself. This
property holds the reference to the
Control on which the
Tooltip instance is
displayed. All we need to do is to add a
Binding to the
that sets the
DataContext of the
ToolTip to the related control.
1 2 3 4 5
The next step we need to take is setting up the Binding
for our attached property
Notifications. Because a
NotificationCollection can contain more than one
Notification I used the
ItemsControl for displaying them in the content area of the tooltip.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
Notifications are finally displayed in the UI.
4. Styling the Notifications
In my initial post I showed a hyphen in front of each Notification. This
is fairly easy to add, too. All you have to do is to define a
DataTemplate for the
Notification class and set it as the
ItemsControl we’re using.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
DataTemplates are also the weapon of choice if you want to
display errors in a different fashion than warnings (for instance by
displaying a different icon). This is where we arrived:
What I like about the current solution is that it demonstrates in a nice
way how different the programming model of WPF actually is compared to
WinForms. The only imperative code we have is the code that transfers
Notifications from our
ViewModel into the logical tree. That’s it. The
rest, the complete visual appeal of the Notifications, is a separated
concern. Those two things can be changed independently from each other,
even by different roles in a development team (Designer/Developer).
Besides that I like the way the composition based WPF model helps my
application code to stay focused and clean with only minimum
implementation constraints on the ViewModel itself (the
INotificationSource interface). There’re certainly things to improve
both in XAML and in the glue code but I consider it a good start to
build on …