Introduction
I am always looking at ways to reduce maintenance and work, and when I was required to put a header on a tile that included the count of records contained in the tile I immediately decided to create a ValueConverter
that was bound to the ItemsSource
of the ListBox
(or Grid
), and took a string that indicated how to combine the count into a string in the ConverterParameter
. Since the easiest way to insert the count of items in an arbitrary string is use the string.Format
method, this determined how to format the string for the ValueConverter
. It also has the advantage in that it is usually easy to include in XAML without special formatting and programmers are familiar with using the string.Format
method.
XAML Usage and Comparison
If one wants to compose a string using bound values in WPF, a lot of elements are required:
<WrapPanel Grid.Row="3" Orientation="Horizontal">
<TextBlock Text="This is the harder way to say that 'User "/>
<TextBlock Text="{Binding UserName}"/>
<TextBlock Text=" has "/>
<TextBlock Text="{Binding Count}"/>
<TextBlock Text=" records'"/>
</WrapPanel>
This is fairly verbose, and requires a lot of visual elements. If the converter is used for the same thing, it is about as verbose, but much easier to understand:
<TextBlock Grid.Row="2" Grid.Column="0">
<TextBlock.Text>
<MultiBinding Converter="{local:StringFormatConverter}"
ConverterParameter="User {1} has {0} records">
<Binding Path="Children" />
<Binding Path="UserName" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
Relatively speaking, having only two arguments is probably the worst case since a single argument could use a standard ValueConverter
, and would not require the MultiConverter
; the MultiConveter
requires the binding to be broken out into elements. However, each extra argument only adds a line. The layout also makes it easier to understand since the format string is in a single attribute, and the bindings are together. The disadvantage is that no longer have the control over formatting each Visual Element.
Note on Collections
The converter will return the count of records if bound to a generic IEnumerable
collection. It will also return the count of records for a DataTable
. However, unless the PropertyChanged
event is executed for the collection property, the count will not be updated. This is even true for an ObservableCollection
. Not sure about the reason since a control that handles a list will be updated.
History
08/09/15: Initial version.