IanG on Tap

Ian Griffiths in Weblog Form (RSS 2.0)

Blog Navigation

August (2014)

(1 item)

July (2014)

(5 items)

April (2014)

(1 item)

March (2014)

(1 item)

January (2014)

(2 items)

November (2013)

(2 items)

July (2013)

(4 items)

April (2013)

(1 item)

February (2013)

(6 items)

September (2011)

(2 items)

November (2010)

(4 items)

September (2010)

(1 item)

August (2010)

(4 items)

July (2010)

(2 items)

September (2009)

(1 item)

June (2009)

(1 item)

April (2009)

(1 item)

November (2008)

(1 item)

October (2008)

(1 item)

September (2008)

(1 item)

July (2008)

(1 item)

June (2008)

(1 item)

May (2008)

(2 items)

April (2008)

(2 items)

March (2008)

(5 items)

January (2008)

(3 items)

December (2007)

(1 item)

November (2007)

(1 item)

October (2007)

(1 item)

September (2007)

(3 items)

August (2007)

(1 item)

July (2007)

(1 item)

June (2007)

(2 items)

May (2007)

(8 items)

April (2007)

(2 items)

March (2007)

(7 items)

February (2007)

(2 items)

January (2007)

(2 items)

November (2006)

(1 item)

October (2006)

(2 items)

September (2006)

(1 item)

June (2006)

(2 items)

May (2006)

(4 items)

April (2006)

(1 item)

March (2006)

(5 items)

January (2006)

(1 item)

December (2005)

(3 items)

November (2005)

(2 items)

October (2005)

(2 items)

September (2005)

(8 items)

August (2005)

(7 items)

June (2005)

(3 items)

May (2005)

(7 items)

April (2005)

(6 items)

March (2005)

(1 item)

February (2005)

(2 items)

January (2005)

(5 items)

December (2004)

(5 items)

November (2004)

(7 items)

October (2004)

(3 items)

September (2004)

(7 items)

August (2004)

(16 items)

July (2004)

(10 items)

June (2004)

(27 items)

May (2004)

(15 items)

April (2004)

(15 items)

March (2004)

(13 items)

February (2004)

(16 items)

January (2004)

(15 items)

Blog Home

RSS 2.0

Writing

Programming C# 5.0

Programming WPF

Other Sites

Interact Software

Binding to the Current Item in WPF

Monday 3 September, 2007, 11:17 PM

When working with collection-like data sources in WPF, you can read properties of the selected item by writing your binding expressions as though there were only one source object. Here’s an example:

<DockPanel DataContext="{x:Static Fonts.SystemFontFamilies}">
  <TextBlock DockPanel.Dock="Top"
             Text="{Binding Baseline}" />
  <ListBox ItemsSource="{Binding}"
           IsSynchronizedWithCurrentItem="True" />
</DockPanel>

The data source here is a collection – an array of FontFamily objects. The ListBox displays all of the items in this array. However, the TextBlock has a binding expression that seems to make no sense – it tries to read the Baseline property, and yet the source, an array, has no such property. When WPF encounters a binding to a non-existent property on a collection, WPF has a fallback strategy: it looks for the named property on the current item. Consequently, the TextBlock shows the Baseline property of the currently selected font.

This is jolly useful, but what do you do in situations where fallback doesn’t occur? For example, suppose you want to bind to the whole of the current item. Usually, a {Binding} with no path has that effect:

<TextBlock DockPanel.Dock="Top" FontFamily="{Binding}"
  Text="The quick brown fox jumps over the lazy dog." />

However, this doesn’t work here. WPF’s alternate behaviour only kicked in for the {Binding Baseline} example because arrays don’t have Baseline properties. Conversely, {Binding} is perfectly valid for an array, so WPF sees no need to fall back to an alternative interpretation. Unfortunately, this ends up trying to set the FontFamily to an array of fonts, which fails. (This failure doesn’t trigger the fallback behaviour. That happens only if the binding cannot be evaluated. A binding that evaluates to an unsuitable type is insufficient.)

So how do we indicate that we want the current item, rather than the whole collection? Here’s how:

<TextBlock DockPanel.Dock="Top" FontFamily="{Binding /}"
  Text="The quick brown fox jumps over the lazy dog." />

In case the difference isn’t leaping out at you, there’s an extra “/” in the binding expression.

This struck me as less than totally obvious. (Hence this blog.) Indeed, I wasn’t even confident this would work first time I tried it. However, it makes some sense after a bit of thought. The main thing is to understand how this relates to a more common syntax:

Property="{Binding Items/Name}"

This binding expression means: the Items property of the source is a collection; get the currently selected item in that collection, and read the Name property.

In general, leaving out a property name in a binding path indicates that you want the whole object rather than a specific property. For example:

Property="{Binding Items/}"

This means: the Items property of the source is a collection; return the current item from that collection. Likewise:

Property="{Binding /Name}"

This means: the source is a collection; get its current item and then return that item’s Name property. Indeed, this last form is arguably what we should have used earlier. The expression {Binding /Baseline} would indicate explicitly that we want the Baseline of the current object, whereas {Binding Baseline} relies on WPF having to guess that this was what we meant. One could argue that we should always use this form for this purpose, except the syntax looks misleadingly like some sort of file path or URL.

Having understood the two variants where we leave out one or other property name, it’s relatively straightforward to interpret the form with no name on either side.

Property="{Binding /}"

This means: the source is a collection; return the currently selected item in that collection. Or more succinctly: bind to the currently selected item.

Copyright © 2002-2013, Interact Software Ltd. Content by Ian Griffiths. Please direct all Web site inquiries to webmaster@interact-sw.co.uk