Friday, 26 March 2010

An easier way to set up diff and merge tools for Git on Windows

I've noticed a fair number of people are looking at my older posts on setting up diff and merge tools and the update on configuring git difftool. These posts cover how to write wrapper scripts around your diff and merge tool of choice (I was using DiffMerge at the time) and get Git to use them.

I'm not doing this any more, opting for a much simpler method. I thought I'd share it in the event you just want to get something up and running as fast as possible, and that you aren't too particular about which diff tool you use.

First step, install KDiff3. It's not the prettiest GUI in the world, but once you get used to it it is quite usable and has the added advantage of working quite naturally with Git without having to configure much.

Second step, open your .gitconfig (in your home directory, C:\Users\(username), or down ye olde Documents and Settings path), and add the following:

[diff]
    tool = kdiff3

[merge]
    tool = kdiff3

[mergetool "kdiff3"]
    path = C:/Program Files/KDiff3/kdiff3.exe
    keepBackup = false
    trustExitCode = false

Now all calls to git difftool and git mergetool should default to KDiff3. That's all you need to be good to go! Much simpler than bothering with all those wrappers. Hope this helps! :)

Certified as working on my machine, running Git 1.7.0.2 (msysgit).

Tuesday, 23 March 2010

A WPF newbie battles the StackPanel

I had a number of prospective titles dreamed up for this post, including:

  • I fought the StackPanel and the StackPanel won
  • StackPanel: you keep using that word. I do not think it means what you think it means
  • Why the !@#$ isn't my TextBox scrollbar appearing?
  • Everytime you use a StackPanel the CLR drowns a kitten
  • Pure evil and StackPanels: BFFs

In the end, I decided to curb my hatred for this loathesome WPF control, and simply continue along the same vein as my previous WPF newbie post. After all, StackPanels don't really kill kittens; VB programmers do. (joking! Unless there are no VB coders reading... ;) :P)

An innocent request

I only wanted to do something really simple. I didn't think I was being at all demanding. I just wanted a TextBox with a scrollbar. This had always just worked for me before. To see what I mean, let's start a new WPF project and create a new WPF Window XAML file. We'll just whack in a TextBox with vertical scroll bar enabled and bask in the XAMLily glory of WPF:

<Window x:Class="WpfApplication1.MainWindow" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <TextBox VerticalScrollBarVisibility="Auto" AcceptsReturn="True" />
</Window>

You can see that as I resize the window, our TextBox resizes to fit the area, and the scrollbar appears as required.

Now we want to add a simple label on top. We don't need a Grid for this right? We just want to stack a Label or TextBlock on top of our TextBox. Stack, huh? This handy StackPanel thing should be just what we need! There's absolutely no way this will be able to waste the better part of our day...

The problem

<!-- Window cruft omitted -->
<StackPanel Orientation="Vertical">
    <TextBlock>Enter stuff in here:</TextBlock>
    <TextBox VerticalScrollBarVisibility="Auto" AcceptsReturn="True" />
</StackPanel>

After running this the first thing we notice is that without text in it, our TextBox does not fill up all the remaining space in the window. When we paste in a chunk of text the box resizes to fit it in, but what happens when we try and resize the window? Hey, where's our scrollbar?!?!

StackPanel size

I have read up a number of times on how WPF layout passes work. I have also promptly forgotten this information each time I've read it. So if you want to know the real reason for this behaviour then it would be a great idea to read up on this from a reliable source. If instead you want to get a vague idea from the ignoramous pounding dumbly away on the keyboard to bring you this post, then read on! :)

As I understand it the problem is the StackPanel (delightful little control that it is) is happy to expand indefinitely in whatever direction it is oriented. In the case of our vertically aligned panel, the child controls will fill out to the horizontal size of the StackPanel, but the StackPanel will not constrain their vertical size.

Instead the vertical size of the child controls will be determined by their own contents, rather than using height available to the parent panel. The minimum height of the StackPanel will in turn be determined by the heights of its child controls. When the StackPanel is rendered within the space available from its parent, any overflow will be clipped, rather than the StackPanel resizing and passing on its size to its children.

In our case, this means that when we resize the window, our StackPanel and its children will keep their actual heights and the overflow (like half our TextBox) will get clipped. The TextBox can't know to display a scrollbar, because it is still the same height: a height which has expanded to fit its contents. (You can see this in action if you Snoop the actual height of the StackPanel and its parent as you resize the window.)

Note: Before you suggest trying to set VerticalAlignment or VerticalContentAlignment to stretch somewhere in the hierarchy, forget it. The StackPanel will keep expanding indefinitely, so you can't stretch its child controls to take up all the available space. Learning that took several hours of setting everything I could find to stretch. (It was a more complex example, I should have tried a minimal case like this one over trial and error. :-\)

Ditching the StackPanel

One way to semi-fix this is to wrap our StackPanel in a ScrollViewer control:

<ScrollViewer VerticalScrollBarVisibility="Auto">
  <StackPanel ... />
</ScrollViewer>  

The ScrollViewer will try and cover-up the StackPanel's refusal to resize by scrolling the StackPanel and its contents instead of clipping the overflow. This doesn't work that well in our case, as it will also scroll our "Enter stuff in here:" prompt that is within the StackPanel.

The other solution is to use a decent layout container instead:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>        
    <TextBlock Grid.Row="0">Enter stuff in here:</TextBlock>
    <TextBox Grid.Row="1" VerticalScrollBarVisibility="Auto" AcceptsReturn="True" />
</Grid>

Sure, it's a bit more work to use a Grid, but it has the added advantage of working. :) Our first row definition is set to automatically determine the height (which will use the height of the row contents), while the second definition uses a star (*), which tells the grid we want to use whatever height is available for this row.

Note: There is lots more you can do with Grid row and column sizing., such as proportionally distributing available space between rows and columns. But for this example, the explanation above is close enough to correct.

And now everything works as expected:

Update: Kevin Berridge wrote in to note that a DockPanel will work here too. And he is quite right. The reason I'm using a Grid is I want to get StackPanel-like ability to stack any number of items. The example presented here is a simplified version of the problem I encountered which had 7 stacked controls, each containing 2 other stacked controls. For this case I used a DockPanel for the inner 2 controls, and a Grid for the 7 outer controls. The important thing here is that regardless of what container you choose, just make sure it's not a StackPanel! ;)

Conclusion

The StackPanel isn't really evil; it's just fairly useless for the layout I was trying to achieve. In fact, I'd go so far to say that in many (most?) cases it is pretty useless (how often will you want your controls to clip?).

From now on my default choice for stacked layouts will be a Grid with a single row or column. I find the cell assignments (Grid.Row="0") to be annoying noise, but at least I know my contents should generally resize sensibly.

Funny thing was that I had come across this months ago when first spiking a WPF application, but it took almost a day of battling the StackPanel again today before I remembered it. This time I'm blogging it to make sure it sticks! :)

Hope this spares you from experiencing the same pain. :)

Monday, 15 March 2010

Using conventions and StructureMap to wire up Views and View Models

In the small WPF project I'm currently working on we are using MVVM (Model - View - ViewModel) to separate our UI concerns from other logic.

Now for various reasons we've ended up with two main projects (excluding tests): the core application DLL, and the WPF UI executable that references the core DLL. Our ViewModels are defined in the application DLL, which knows absolutely nothing about the UI executable. Our Views (XAML) live in the UI exe, and depend on the ViewModels in the core DLL. All pretty standard.

The one hiccup is that sometimes our application DLL needs to do something that will result in getting a reference to a view. For example, an application controller, screen conductor, or in our case, an ApplicationShellViewModel needs to load up the relevant views (it's a small project, remember? :)). So how does it do this when it knows nothing about the views in the UI exe?

In this case we decided to use a convention to map a ViewModel to a View. We've mandated that each View will have one and only one ViewModel (not strictly always the case, but works for us). So we can use our ViewModel types as "currency" to deal with our views, and exchange it for a view when required. We just need a way to map between a ViewModel and its View.

The way we decided to do this mapping is to use an IView marker interface (defined in the core DLL) on all our views in the UI exe, and use a ViewFactory class to resolve an IView based on the name of a ViewModel, with the help of our IoC container (StructureMap 2.6). The naming convention we'll use is very simple: if we have a GherkinViewModel, we expect the matching view to be of type Gherkin. If you're new to IoC containers this all probably sounds a little confusing, so let's look at some code.

Note: This is probably a good time to stress that this post isn't about great ways to wire up MVVM components. It is more an example of using conventions and StructureMap to implement a fairly naive approach to View/View Model wire-up. If you are after more the former than the latter then you may want jump over to Nikhil's post on View/ViewModel association. I won't take it personally. :)

The ViewFactory

Given a ViewModel type, we want our ViewFactory to get an instance of the IView for that view model using our naming convention. Let's write a test for this, specifying that we want to resolve an IView named "Example" for our ExampleViewModel:

public class ViewFactoryFixture {
    [Test]
    public void ShouldResolveViewForViewModelUsingNamingConvention() {
        var exampleView = MockRepository.GenerateStub<IView>();
        var applicationFactory = MockRepository.GenerateStub<IApplicationFactory>();
        var viewFactory = new ViewFactory(applicationFactory);
        applicationFactory.Stub(x => x.ResolveNamed<IView>("Example")).Return(exampleView);

        var result = viewFactory.CreateViewFor<ExampleViewModel>();

        Assert.That(result, Is.SameAs(exampleView));
    }

    public class ExampleViewModel {}
}

The ViewFactory will need to use our IoC container to resolve the instance, which we've wrapped in an IApplicationFactory interface (not the best name perhaps -- it creates application objects). Our test is specifying that when we ask the ViewFactory to create a view for our ExampleViewModel type, it should return the instance resolved from the IApplicationFactory named "Example". Let's pass this:

public class ViewFactory : IViewFactory {
    private IApplicationFactory _applicationFactory;

    public ViewFactory(IApplicationFactory applicationFactory) { _applicationFactory = applicationFactory; }

    public IView CreateViewFor<TViewModel>() {
        var viewNameByConvention = typeof (TViewModel).Name.Replace("ViewModel", "");
        return _applicationFactory.ResolveNamed<IView>(viewNameByConvention);
    }
}

Now we just need to implement an IApplicationFactory class and we're done.

Registering named views in StructureMap

For our project our core StructureMap configuration lives in the core application DLL -- the one with no references to the UI exe that has our views. Thankfully StructureMap has a really nice way of looking through assemblies and wiring up types you're interested in.

class CoreRegistry : Registry {
    public CoreRegistry(IApplicationFactory applicationFactory) {
        For<IApplicationFactory>().Use(applicationFactory);
        Scan(x =>
            {
                x.AssembliesFromApplicationBaseDirectory(
                    assembly => assembly.FullName.StartsWith("DaveSquared."));
                x.AddAllTypesOf<IView>().NameBy(type => type.Name);
                x.WithDefaultConventions();
            });
    }
}

Registry is a StructureMap type that is used to configure the container. We're telling StructureMap to scan the assemblies in the application base directory, and add those that are specific to this project (which in this example will be DaveSquared.MvvmConventionWireup.Core and DaveSquared.MvvmConventionWireup.UI). The magic happens in this line:

x.AddAllTypesOf<IView>().NameBy(type => type.Name);

Here we're telling the StructureMap scanner to add all types that implement IView into the container, and name each specific type by the short type name. This, you'll remember, is our naming convention. When asked for the view for ExampleViewModel we'll lookup an IView called "Example" (which will live in the UI project in a Example.xaml file).

Some other quick notes: WithDefaultConventions() tells StructureMap to automatically wireup cases where there is only one concrete type that implements an interface (for example, Foo for IFoo). Also we register a singleton IApplicationFactory instance, as we need this as a dependency into our ViewFactory.

The last step is just to put this altogether for our IApplicationFactory implementation:

public class ApplicationFactory : IApplicationFactory {
    public ApplicationFactory() {
        ObjectFactory.Initialize(x => x.AddRegistry(new CoreRegistry(this)));
    }

    public T Resolve<T>() {
        return ObjectFactory.GetInstance<T>();
    }

    public T ResolveNamed<T>(string name) {
        return ObjectFactory.GetNamedInstance<T>(name);
    }

    class CoreRegistry : Registry { /* ... snipped, already shown above ... */ }
}
Aside: I can't help but point out that this ApplicationFactory is covered by tests. We make sure we can resolve views by name, and resolve a view factory, and a few other key instances. These are integration tests, but I've made the mistake of not testing this stuff before and having it grow into a real mess, the lack of tests encouraging sloppiness to creep in. There are better ways to test more complex configurations, but this is a nice and simple approach for a nice and simple app.

We can now resolve Views like this from within our core application DLL code:

public ApplicationShellViewModel(IViewFactory viewFactory) {
    Top = viewFactory.CreateViewFor<FunkyViewModel>();
    Bottom = viewFactory.CreateViewFor<AwesomeViewModel>();
}
public IView Top { get; set; }
public IView Bottom{ get; set; }
Note: Check out Prism / Composite WPF or Caliburn for real ways to do view composition. :)

Final thoughts

This post has shown a basic example of how to use conventions to resolve Views from ViewModels in situations where you don't want to have hard references to View types. I have no idea if this is a blatant misuse of StructureMap or IoC containers in general (please correct me! :)), but it is working fine for us at the moment. It is especially nice to just name a View and have it auto-magically wireup to its ViewModel. It's not quite as nice for the poor designer, but in our case we're only doing fairly basic UI for which I've found it easier to deal directly with the XAML.

One thing to keep in mind is that our ViewFactory and ApplicationFactory classes reference our container, which means we want to be very careful how widespread their use becomes in the application. Ideally you only want a couple of references to your IoC container in your application, so for us we only have it referenced in the class that handles our startup, and in our application shell (which is playing the role that an application controller or screen conductor might play in a larger app).

Hope this gives you some idea of how easy it is to get some simple conventions going in your code. If I've glossed over anything you'd like to know more about feel free to drop me a line.

Monday, 8 March 2010

StructureMap gotcha: IEnumerable<T> instance registered but not injected

This had me stumped for a long time a few days back, so I thought I'd post it in case it trips up anyone else as well. This gotcha applies when asking StructureMap (v 2.5+) to resolve a type which needs an array or other IEnumerable<T> injected.

Much ado about somethings

Say I have the following code:

public class Something { }

public class SomeClass {
    public IEnumerable<Something> Somethings { get; private set; }
    public SomeClass(IEnumerable<Something> somethings) {
        Somethings = somethings;
    }
}

I would like to ask StructureMap, our friendly neighbourhood IoC container, to resolve an instance of SomeClass for me, injecting a specific IEnumerable<Something> instance into the constructor call. Piece of cake!

public class Bootstrapper {
    public static readonly IEnumerable<Something> ThreeSomethings 
          = new[] { new Something(), new Something(), new Something() };

    public static void Start() {
        ObjectFactory.Initialize(x =>
            {
                x.For<IEnumerable<Something>>().Use(ThreeSomethings);
            });
    }
}

Let's check our ObjectFactory is resolving our IEnumerable correctly:

[Test]
public void ShouldResolveEnumerableOfThreeSomethings() {
    Bootstrapper.Start();
    var somethings = ObjectFactory.GetInstance<IEnumerable<Something>>();
    Assert.That(somethings, Is.EquivalentTo(Bootstrapper.ThreeSomethings));
}

It passes. Too easy! Now let's get our SomeClass instance and start work!

[Test]
public void ShouldResolveSomeClassWithThreeSomethings() {
    Bootstrapper.Start();
    var someClass = ObjectFactory.GetInstance<SomeClass>();
    Assert.That(someClass.Somethings, Is.EquivalentTo(Bootstrapper.ThreeSomethings));
}

Er, that test fails. According to NUnit, it expected 3 somethings, but it got an empty enumerable. But hang on, we already tested we had registered and can resolve our IEnumerable<Something>, and it's still passing! So what's going on?

Auto-wiring of IEnumerable<T> types in StructureMap

As of version 2.5 and later, StructureMap has special handling for injecting IEnumerable<T> types including arrays, lists of T, and IEnumerable<Something>. Rather than looking for a specific, registered instance of the enumerable itself, it will just inject all registered instances of type T.

In our case we have registered an IEnumerable<Something>, but no Something instances. StructureMap's special handling for the enumerable type injects all our registered instances, i.e. an empty enumerator. We can fix it by changing our ObjectFactory.Initialize expression to explicitly add each instance:

ObjectFactory.Initialize(x =>
    {
        x.For<IEnumerable<Something>>().Use(ThreeSomethings);
        foreach (var something in ThreeSomethings) {
            x.For<Something>().Add(something);                    
        }
    });

This passes both tests, although we probably don't care so much about directly resolving an IEnumerable<Something> anymore, so we could take out the x.For<IEnumerable<Something>>().Use(ThreeSomethings); line from the initialisation block and remove that test.

Workarounds (ssshh, don't do this!)

If you really (really!) don't want to use this officially sanctioned method of injecting enumerables, you can override the behaviour by telling StructureMap what to use for that specific constructor argument:

x.ForConcreteType<SomeClass>()
  .Configure
    .Ctor<IEnumerable<Something>>()
    .Is(ThreeSomethings);

Or better yet, wrap your enumerable in a new class or interface with more relevance to the domain instead of the built-in framework type. If SomeClass took a Somethings class instead of an IEnumerable<Something> then StructureMap would wire it up in the standard way.

Hope this saves someone the couple of hours of hair-tearing it cost me. :)

Tuesday, 2 March 2010

A WPF newbie styles a ListBox

Hi, I'm Dave, and I'm a WPF newbie. In this post I jump headlong into the exciting world of styling a WPF ListBox, coming face to face with creatures such as templates, styles, brushes and resources.

The aim of this exercise is to display some widgets that the user can select. A widget has both a Name and a Quantity. I've got a WidgetListViewModel with a public ObservableCollection<Widget> property called Widgets that our view will bind to. If you're not familiar with the basics of MVVM, you can get a quick introduction from my attempt at simple MVVM with WPF.

Simple data-binding

Let's start with our basic view, WidgetListView.xaml:

<Window x:Class="DaveSquared.StylingListBox.WidgetListView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Widgets" Height="350" Width="525">
    <ListBox ItemsSource="{Binding Widgets}"/>
</Window>

Here we are setting the ItemsSource of our ListBox to bind to something called Widgets. WPF works out what to do with this by search this control's DataContext for a public property with the same name. If it can't find it, it will check the control's parent, parent's parent etc. until it urns out of parents or finds the property to bind to. In this case I've set the DataContext of our window to our view model in the codebehind, WidgetListView.xaml.cs:

public partial class WidgetListView : Window {
    public WidgetListView(WidgetListViewModel viewModel) {
        InitializeComponent();
        DataContext = viewModel;
    }
}

As this view model has a Widgets property, the binding resolves correctly and we get a not-so-useful list of type names:

By default, the binding process will just call ToString() on each object. As my Widget class doesn't implement ToString() we get the default behaviour from Object, which is just the type name. We can fix this by telling our binding to use a specific member for each item. Let's try using the Name property on each widget.

<ListBox ItemsSource="{Binding Widgets}" DisplayMemberPath="Name" />

Displaying more information using DataTemplates

We can now see the name of each widget, but say we also want to display the quantity. One way of doing this is to specify a DataTemplate. We can put this directly in our ListBox using ListBox.ItemTemplate (which we'll see in the final example), but for now let's look at how to do this using a DataType-specific template.

<Window x:Class="DaveSquared.StylingListBox.WidgetListView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:local="clr-namespace:DaveSquared.StylingListBox" 
        Title="Widgets" Height="350" Width="525">
    <Window.Resources>
        <DataTemplate DataType="{x:Type local:Widget}">
            <Border CornerRadius="10" BorderBrush="Black" BorderThickness="1" Margin="1">
                <StackPanel Orientation="Horizontal">
                    <Label Content="{Binding Name}" />
                    <Label Content="{Binding Quantity}" />
                </StackPanel>
            </Border>
        </DataTemplate>
    </Window.Resources>
    <ListBox ItemsSource="{Binding Widgets}" HorizontalContentAlignment="Stretch" />
</Window>

Resources are a way to resuse different elements within WPF. In this case we are adding a DataTemplate to our Window.Resources resource dictionary, so this template can be reused in many places around the window. In this case it isn't too useful, but it does give some separation between the layout of our main UI elements (our ListBox), and the specific rendering used for it.

When we run the application, we see each widget rendered with its name and quantity, surrounded by a cheesy looking border:

So how does this work? The ListBox doesn't have any specific attributes linking it to our DataTemplate. On the template itself however is a DataType attribute that has a cryptic {x:Type local:Widget} value. This is telling WPF that we want this template to be used whenever rendering a bound object of type Widget. The x:Type string tells WPF the attribute is referring to a type (sort of like XAML's equivalent of typeof). The local: prefix also looks a bit odd. If you check the Window node you'll see an xmlns:local attribute that has a value of "clr-namespace:DaveSquared.StylingListBox". This is mapping the namespace of my project into XAML, so local:Widget resolves to the DaveSquared.StylingListBox.Widget type.

So each widget ends up getting its border, and two labels arranges horizontally thanks to a StackPanel. We've also had to add a HorizontalContentAlignment="Stretch" attribute to our listbox, other wise each listbox item would be a different width depending on its name's length. Telling the listbox to stretch its items horizontally makes each item take up the full width of the listbox. We didn't need to worry about this before as we didn't have a border to make the width obvious.

Adding a touch of style

There's a few interesting things happening with our current code. First, the highlighting of the selected item does not take any notice of our border, so it just highlights the entire item, which looks a bit strange. The second thing to notice is that we are mixing data-binding specific markup (binding to our name and quantity properties) with more general presentation concerns (putting rounded borders around items). Let's look at fixing the second issue, as it will end up helping us with the first.

Now rounded borders don't have any relation to widgets; we could easily imagine having sprockets or doodads displayed with rounded borders. So let's separate the widget-specific markup from our general item style. Let's see the XAML first, then we'll step through it.

    <Window.Resources>
        <Style x:Key="RoundedItem" TargetType="ListBoxItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <Border CornerRadius="10" BorderBrush="Black" BorderThickness="1" Margin="1">
                            <ContentPresenter />
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <DataTemplate DataType="{x:Type local:Widget}">
            <StackPanel Orientation="Horizontal">
                <Label Content="{Binding Name}" />
                <Label Content="{Binding Quantity}" />
            </StackPanel>
        </DataTemplate>
    </Window.Resources>
    <ListBox ItemsSource="{Binding Widgets}" ItemContainerStyle="{StaticResource RoundedItem}" HorizontalContentAlignment="Stretch" />

Here we've moved the non-binding specific markup from our DataTemplate into a Style. We've given it a key so we can refer to it by the string "RoundedItem", and set a target type so it can be applied to any ListBoxItem. If we don't set a target type, then we won't be able to access any ListBoxItem specific properties.

Aside: We don't have to do the whole {x:Type} thing to refer to ListBoxItem. I'm not sure why, but it is probably something to do with it being a built-in WPF type. Maybe the type converter automatically searches built-in types.

Our RoundedItem style is going to set the Template property of the styled ListboxItem to be the ControlTemplate we specify, which is just our cheesy rounded border. Inside the border element is a <ContentPresenter /> node. This is going to render our item with whatever template is applied to the contents. In our case, this is our existing DataTemplate, which now just contains the widget-specific binding markup. The style is being applied to the ListBoxItem container, whereas the template is being applied to the bound widget. They are linked by the ContentPresenter element in the style.

To apply this we just add a ItemContainerStyle="{StaticResource RoundedItem}" attribute to our ListBox. (Note: ListBox.Style will apply to the listbox itself, whereas ListBox.ItemContainerStyle is the style used for each ListBoxItem.) The {StaticResource} value tells WPF to try and find the named resource in its various resource dictionaries (similar to how DataContext is searched for binding). WPF also has a {DynamicResource} which is used for resources that can change, and so need to be reevaluated throughout the life of the control. As our resources for this example are static we won't need that here.

Our app looks the same until we try to select an item and find that it does not get hightlighted. This is because we've overriden the ListBoxItem template that previously did this for us. Luckily we are now in a good position to not only restore the highlighting, but also fix it so it only highlights within the border of the item.

Triggers

To reinstate the highlighting, we can add a trigger to our ControlTemplate in our RoundedItem style to update our item when a particular property changes.

<ControlTemplate TargetType="ListBoxItem">
    <Border Name="ItemBorder" CornerRadius="10" BorderBrush="Black" BorderThickness="1" Margin="1" Background="Transparent">
        <ContentPresenter />
    </Border>
    <ControlTemplate.Triggers>
        <Trigger Property="IsSelected" Value="True">
            <Setter TargetName="ItemBorder" Property="Background" Value="LightBlue" />
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

Here we're telling our template that when the IsSelected property of our ListBoxItem is true, we want the background of our border element set to light blue. Notice we've given the border element a name ("ItemBorder") so that we can refer to it in our trigger's Setter. We also need to specify a starting background (in this case I've set it to transparent), otherwise it won't change back properly when the item is unselected (it needs to have an initial value to revert to).

MultiTriggers

But we don't have to stop there. Let's also change the background when an item is hovered over. Now this one is a bit trickier, as we don't want to change the background of a selected item that is hovered over, only of unselected items (otherwise the selected item will appear to lose its selection). The answer is a MultiTrigger:

<ControlTemplate.Triggers>
    <Trigger Property="IsSelected" Value="True">
        <Setter TargetName="ItemBorder" Property="Background" Value="LightBlue" />
    </Trigger>
    <MultiTrigger>
        <MultiTrigger.Conditions>
            <Condition Property="IsMouseOver" Value="True" />
            <Condition Property="IsSelected" Value="False" />
        </MultiTrigger.Conditions>
        <Setter TargetName="ItemBorder" Property="Background" Value="Azure" />
    </MultiTrigger>
</ControlTemplate.Triggers>

Here we've set two conditions necessary for the multitrigger to be applied, IsMouseOver must be true, and IsSelected must be false. If these conditions are satisfied then we'll set the background to azure, and get this effect:

Tidying up

I mentioned earlier that resources enabled us to share styles and templates across controls, windows or even applications. We can even create and load resource dictionaries to provide different themes for applications. Let's move some of the more general pieces of markup into our application dictionary. To do this, we'll open our App.xaml (or whatever Application class we have) and drop our RoundedItem style in there.

<Application x:Class="DaveSquared.StylingListBox.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             >
    <Application.Resources>
        <SolidColorBrush x:Key="ItemBrush" Color="Transparent" />
        <SolidColorBrush x:Key="SelectedItemBrush" Color="LightBlue" />
        <SolidColorBrush x:Key="HoverItemBrush" Color="Azure" /> 
        <Style x:Key="RoundedItem" TargetType="ListBoxItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <Border Name="ItemBorder" CornerRadius="10" BorderBrush="Black" BorderThickness="1" Margin="1" Background="{StaticResource ItemBrush}">
                            <ContentPresenter />
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="True">
                                <Setter TargetName="ItemBorder" Property="Background" Value="{StaticResource SelectedItemBrush}" />
                            </Trigger>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="IsMouseOver" Value="True" />
                                    <Condition Property="IsSelected" Value="False" />
                                </MultiTrigger.Conditions>
                                <Setter TargetName="ItemBorder" Property="Background" Value="{StaticResource HoverItemBrush}" />
                            </MultiTrigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Application.Resources>
</Application>

Here we've also pulled out the brushes we're using to paint our border backgrounds. This will allow use to use common colours for selected and hovered-over screen elements. This means we can get a much lighter view:

<Window x:Class="DaveSquared.StylingListBox.WidgetListView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Widgets" Height="350" Width="525">
    <ListBox ItemsSource="{Binding Widgets}" ItemContainerStyle="{StaticResource RoundedItem}" HorizontalContentAlignment="Stretch">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <Label Content="{Binding Name}" />
                    <Label Content="{Binding Quantity}" />
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Window>

As I mentioned towards the beginning of this post, we can also stick our DataTemplate directly in the listbox using the ListBox.ItemTemplate. We've done so here to get rid of our specific Window resources, and we no longer need to directly specify the target type of the template. I probably should have done this to begin with, but at least we got to see how target types work. :)

Now you can do much more with this stuff, but at least we've covered some of the key elements we need to apply styles and templates to our WPF controls. Hope this helps any fellow WPF newbies out there. Comments and corrections welcomed.