Customizing the selected item in a ListBox

July 30, 2007

This blog post demonstrates how to make the selected ListBoxItem in a ListBox display differently than unselected items.  We will see how to add an extra Button to the selected item, but you can add whatever you want by using the technique shown below.  This is what the demo app looks like when you run it and select an item:

Customized SelectedItem (screenshot)

The trick is to set the ListBox’s ItemTemplate to a DataTemplate which knows when to expose the extra visuals for the selected item(s).  Here’s an example of a template which knows how to do that:

 Customized SelectedItem (template)

That DataTemplate creates two Grids.  The outer Grid has two rows: the top row is for the normal item content, and the bottom row hosts the selected item’s extra content.  The inner Grid is in the bottom row.  That inner Grid has a Style which knows when to hide itself (i.e. when the ListBoxItem is not selected).

Here’s a ListBox which consumes that template:

 Customized SelectedItem (ListBox)

Download the demo project here: Customized SelectedItem (Demo) Be sure to change the file extension from .DOC to .ZIP and then decompress it.


Article about creating skinned UIs

July 27, 2007

I just published a new WPF article to CodeProject.  It explains the basics how to design and implement a “skinned” user interface, which means that you can very easily apply different visual styles to a UI at compile-time or runtime.  If you’re interested in this topic, here’s a link to the article: http://www.codeproject.com/useritems/SkinningInWPF.asp


Chris Anderson on WPF

July 27, 2007

An interview with Chris Anderson, one of the chief architects of WPF, was recently posted here.  It is a very interesting 24 minute discussion about WPF.  Anderson provides insight into why WPF was created, what the platform offers for developers and for architects, how and why teams should migrate to WPF, along with several other topics.


A lightweight alternative to DropShadowBitmapEffect

July 24, 2007

This blog post reviews how to create drop shadows around WPF elements in a way which does not have a noticeable impact on an application’s UI performance.

One of the biggest letdowns about the first version of WPF is the fact that bitmap effects are so terribly slow.  The most commonly used bitmap effect is the one which creates a drop shadow around an element; the DropShadowBitmapEffect.  If you start using that class to create drop shadows you will soon find your UI performance suffering immensely.  This is a shame considering how visually appealing a well-placed drop shadow can be.

Here is a screenshot which shows a ListBox with a drop shadow.  The drop shadow was created by adding a DropShadowBitmapEffect to the ListBox’s BitmapEffects collection.

Lightweight DropShadows (using DropShadowBitmapEffect)

If you were to repeatedly resize that Window, you would find that the rendering of the ListBox flickers and is slow.  Why?  The problem is that bitmap effects are not hardware accelerated, and they can execute quite often.  WPF’s support for bitmap effects requires them to be created in unmanaged code (usually C++).  There is currently no way to hardware accelerate those unmanaged routines.  I suppose it is possible to write your own bitmap effects which run themselves on a graphics card’s GPU, but that is way beyond the scope of this post!!

Fortunately there is an easy way to create drop shadows around WPF elements which does not incur any noticeable performance overhead.  The trick is to decorate an element with a SystemDropShadowChrome element.  SystemDropShadowChrome does not have nearly as many settings that you can adjust, but it provides a decent drop shadow for many situations.  Here’s a screenshot of a ListBox which is decorated with that element:

Lightweight DropShadows (usign SystemDropShadowChrome)

SystemDropShadowChrome lives in an obscure assembly and namespace.  If you want to use it, you must add a reference to one of the PresentationFramework.* assemblies (there are currently .Aero, .Luna, .Royale, and .Classic).  You will find the class in the Microsoft.Windows.Themes namespace. 

Each of the PresentationFramework.* assemblies has its own version of the SystemDropShadowChrome class, but after checking them out in Reflector I found out that they are all exactly the same.  Someone must have written the class once, and then pasted it into each of those assemblies.  So, there is no need to worry about choosing the “right” class to use at runtime, based on the user’s current operating system theme settings.  Any one of them will do.

In this post’s demo application I chose to reference the PresentationFramework.Aero assembly, as seen below:

Lightweight DropShadows (assembly references)

Once you have the assembly reference in place, you need to map the Microsoft.Windows.Themes namespace in your XAML file, like this:

xmlns:aero=”clr-namespace:Microsoft.Windows.Themes; assembly=PresentationFramework.Aero”

At that point, it’s simply a matter of wrapping an element in a SystemDropShadowChrome element, and perhaps setting its Color and/or CornerRadius properties.  Here is the XAML which does this in the demo project:

Lightweight DropShadows (XAML)

To read another perspective on the SystemDropShadowChrome class, read here.

Download the demo project here: Lightweight DropShadows (demo project)  Be sure to change the file extension from .DOC to .ZIP and then decompress it.


Stretching Content in an Expander Header (take two)

July 18, 2007

A while ago I posted a blog entry called Stretching Content in an Expander Header which discussed a way to make the content of an Expander’s header occupy all available space in the header area.  The solution I proposed back then required the use of some code to do the trick.  Today a fellow by the name of Patrick Jones posted a comment which shows a clean solution.  His solution still requires the use of code.

After reading over his sample I realized that it is possible (and easy) to implement the functionality without writing any code at all.  The original post has been updated to show the XAML-only solution, which I like the best out of all three options (if you do not care that the header element will be clipped on the righthand side).  Here’s the relevant XAML snippet:

<Expander>
  <Expander.Header>
    <TextBlock
      Text=”I am header text…”
      Background=”Blue”
      Width=”{Binding
        RelativeSource={RelativeSource
          Mode=FindAncestor,
          AncestorType={x:Type Expander}},
        Path=ActualWidth}”

      />
  </Expander.Header>
  <TextBlock Background=”Red”>
    I am some content…
  </TextBlock>
</Expander>

NOTE: Be sure to read the original post to learn about the limitations of this XAML-only approach, and when it is necessary to use the original technique.


Writing unit tests for classes that use DispatcherTimer

July 14, 2007

I just published an article on CodeProject which discusses how to write unit tests for classes that depend on DispatcherTimer to get their work done.

It seemed like a pretty straightforward task when I first tried to write a unit test for functionality which uses DispatcherTimer.  Wow, was I wrong!  It was actually a mind-bending experience, which required me to learn a lot about how WPF’s Dispatcher and DispatcherTimer work.  If you want to read more about what I learned along the way, here’s the link: http://www.codeproject.com/KB/WPF/UnitTestDispatcherTimer.aspx


Extending the WPF Command system

July 12, 2007

There is a very interesting thread on the WPF Forum which discusses how to augment the Command system in WPF.  A fellow by the name of Patrick Klug explains how his team made use of the CommandParameter property of CanExecuteEventArgs to pass extra information about the status of a Command.  His post was followed up by Bill Henning, of Actipro Software, who explained how his company’s WPF control library extends the basic Command system to pass more information about a command than is possible by default.  I highly recommend checking it out.

Here’s the link: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1809894&SiteID=1

Thanks for sharing your interesting ideas, guys!


Templates, Styles, and Polymorphism

July 11, 2007

This blog post examines the difference between how DataTemplates and Styles are applied to instances of related classes.  In a nutshell, typed DataTemplates support polymorphism while typed Styles do not.

If you create a DataTemplate where its DataType property is set to a base type it will be used to render an instance of a class which derives from the base type.  In that sense, DataTemplates support polymorphism.  Of course, if you also have another DataTemplate which specifically targets the subclass then that template will be used instead.

On the other hand, a typed Style (i.e. a Style with no x:Key) whose TargetType is set to the base type will not be applied to elements of the derived type.  Styles do not support polymorphism.  For a typed Style to be applied to an object, the Style’s TargetType must exactly match the type of the object.

[EDIT: As Jan Kucera keenly pointed out in a comment below, if you give an x:Key to a Style which targets a base type and then assign that Style to an instance of a subclass's Style property, the Style will be applied to the subclass instance.  This means that there seems to be an inconsistency as to how Styles are applied "polymorphically."  It works if you apply them explicitly to an element, but a typed Style will not be applied to a subclass of its TargetType.]

I was not aware of this difference until recently.  I spent quite a while tracking down what was rendering a particular data object, and eventually realized that the template I was looking for had its DataType set to a base class of the object being displayed.  After realizing that DataTemplates support polymorphism I tested if Styles do as well, and discovered that they do not.

I think the best way to convey this difference is by showing a simple example.  Here are the classes used in the demo app:

Templates Styles and Polymorphism (classes)

Here is the XAML which creates an instance of Foo2 and Button2, and applies a template and style to them:

Templates Styles and Polymorphism (XAML)

If you run the demo application with the XAML seen above, the UI looks like this:

Templates Styles and Polymorphism (screenshot 1)

As you can see based on the XAML seen previously, the Button2 instance is not affected by the Style which targets the Button class.  However, the Foo2 object is rendered by the DataTemplate whose DataType is set to the Foo base class. 

If we were to uncomment the additional DataTemplate and Style seen in the XAML above, the UI would look like this:

Templates Styles and Polymorphism (screenshot 2)

The Button2 and Foo2 are colored red in this situation because the presence of a DataTemplate and Style specific to those types are present at runtime.

You can download the demo app here: Templates Styles and Polymorphism (demo app)  Be sure to change the file extension from .DOC to .ZIP and then decompress it.


Using NUnit with WPF

July 9, 2007

My regular stream of blog posts has recently slowed to a trickle.  I’ve been spending a lot of time on my project at work, and a considerable amount of that effort has gone into creating unit tests with the NUnit v2.4 framework.  In this blog post I share a few tips I have learned along the way about using NUnit with WPF.

First of all, it is important to know that WPF elements must be created on a thread which uses the Single Threaded Apartment (STA) model.  By default, NUnit uses worker threads with the Multithreaded Apartment (MTA) model to run your tests.  If you try to create an element/control in an NUnit test you will quickly see what I mean.

When I first encountered this issue I was working on my laptop in a coffeehouse without an Internet connection.  I spent far too long figuring out a solution which worked.  When I got home and searched for a solution, I immediately found this blog post.  That solution includes a nifty way of keeping an exception’s stack trace valid, so I ended up adopting the code in that post.  Keep in mind that not all testing frameworks use MTA threads to run your tests, so this might not be a problem for people out there creating WPF elements with other unit testing frameworks.

Another point of interest for folks who create unit tests for WPF classes is that the Application.Current property will return null when a unit test executes.  When your unit tests are running there is no Application instance with an active message pump churning away.  If you are testing code which relies on Application.Current then you should consider using dependency injection on that class, so that your test code can inject a dummy Application instance.

For example, you might want to do something like this for the class under test:

 NUnit with WPF (using IoC)

Classes in the application would use the parameter-less constructor, and the test code would use the constructor which accepts an Application instance.

Here is a blog post which contains many useful links related to unit testing WPF code: http://mdavey.wordpress.com/2007/06/14/ui-automation/


Differences between Label and TextBlock

July 4, 2007

I always thought it was odd that WPF has both TextBlock and Label.  They both are responsible for displaying a small amount of text.  Every piece of documentation about Label I have read justifies its existence by mentioning that it allows for access keys (a.k.a. mnemonics).  Access keys allow you to hit Alt + SomeKey to quickly interact with a control in the UI, such as hitting Alt + O to click an “OK” button.  My thought has been, “Why not just add support for access keys to TextBlock and get rid of Label?”

Recently I discovered some reasons why it makes sense for Label to exist.  The rest of this blog post sheds some light on that obscure topic.  Throughout this blog post we will refer to a demo application which looks like this when you first run it:

Label vs TextBlock (initial UI)

The “Username:” text is a TextBlock and the “Password:” text is a Label.

TextBlock is not a control

Even though TextBlock lives in the System.Windows.Controls namespace, it is not a control.  It derives directly from FrameworkElement.  Label, on the other hand, derives from ContentControl.  This means that Label can:

  1. Be given a custom control template (via the Template property).
  2. Display data other than just a string (via the Content property).
  3. Apply a DataTemplate to its content (via the ContentTemplate property).
  4. Do whatever else a ContentControl can do that a FrameworkElement cannot.

Below is a fragment of the class inheritance hierarchy containing Label and TextBlock:

Label vs TextBlock (class hierarchy)

Label text is grayed out when disabled

When a Label’s IsEnabled property returns false its text is “grayed out.”  TextBlock does not have this behavior by default.  Here is what the demo app looks like when the input area is disabled.  Keep in mind that the “Username:” text is a TextBlock and the “Password:” text is a Label:

Label vs TextBlock (disabled)

The reason Label text turns gray when it is disabled is due to the fact that Label’s default control template has a Trigger which explicitly sets the Foreground property when IsEnabled is false.  Here is that Trigger from Label’s default control template:

Label vs TextBlock (Label’s trigger)

If we really wanted TextBlocks to appear grayed out when disabled, we could repurpose that XAML seen above into a Style which is applied to TextBlocks (as seen in the demo project available at the end of this post).

Label supports access keys

This is the standard explanation of why Label exists.  You can associate a Label with another control, such as a PasswordBox, and allow the user to type an access key defined by the Label to set focus to the other control.  The access key is represented in the UI by drawing a line under the appropriate character.  If the user presses the Alt key and then the designated “access character” the target control will be given focus.

Here is what the demo application looks like after the user presses the Alt key:

Label vs TextBlock (access key indicators)

Notice how every piece of text in the UI has an access key indicator, except for the “Username” TextBlock.  The “Password” Label and its target (a PasswordBox) were declared like this:

Label vs TextBlock (setting Label.Target)

Label is much heavier than TextBlock

So far we have examined why Label can be considered better than TextBlock, but now its time to discuss the benefits of using a TextBlock instead.  Label has a higher runtime overhead than TextBlock.  Not only does Label inherit from two classes further down the inheritance hierarchy than TextBlock, but its visual tree is much more involved.

I snooped the visual tree of the demo app to see what was really going on when you create a Label with an access key defined.  Below is a screenshot of Snoop displaying the visual trees of both the “Username” TextBlock and the “Password” Label (with an access key defined):

Label vs TextBlock (snooping the visual tree)

The “Username” TextBlock’s visual tree contains no child elements.  The Label, however, is much more involved.  It has a Border, which contains a ContentPresenter, which hosts an AccessText element, which finally uses a TextBlock to display the text.  So it turns out that using a Label is really just an elaborate and customizable way of using a TextBlock.

Links

Label Class

TextBlock Class

AccessText Class

ContentPresenter.RecognizesAccessKey Property

How to: Create a Control That Has an Access Key and Text Wrapping

Snoop (a WPF utility)

Download the demo

Download the demo project here: Label vs TextBlock (demo project)  Be sure to change the file extension from .DOC to .ZIP and then decompress it.


Follow

Get every new post delivered to your Inbox.

Join 273 other followers