I'm pretty busy at present, hence I haven't had much time to write new blog entries. However, today I came about a thread in the WPF forum where the OP asks for a way to concatenate multiple fields for a binding. Now, since I (IIRC) have written about this several times in the forums (I guess everybody at one time will stumble over that - I did) and this is actually something that sure qualifies for a less-than-30-minutes-blog-entry (edit: ... or so I thought; I recently updated to BlogEngine 1.6 and the code-formatter was giving me one hell of a hard time!), I thought I'd write another quickie, so here's what I'm using as a sort of generic approach for stuff like this.
Note that, even though I only present C# code in this article, the sample solution (see the bottom for the download) contains both a project for C# and VB.
Edit (April 21st 2010)
Please note that I had to find out that the Converter I'm introducing here isn't even required to do the job outlined in this article. See the last paragraph (But wait!) for more information.
I'm leaving the blog-post here anyway (might as well help to teach somebody else the same lesson
). And, as of April 30th 2010, I'm again turning around 180°, stating that the Converter is useful (again, see the bottom of this post).
The problem
The class that provides the data for your window has i.e two fields that are to be shown in a single column of a ListBox (or ListView, GridView, you name it). The classical fields are the LastName/FirstName combos.
The sample data
For the remainder of the blog, I've created a simplistic class Person, that will only provide the two properties LastName and FirstName. Here it is:
public class Person
{
private string _LastName;
public string LastName
{
get { return _LastName; }
set { _LastName = value; }
}
private string _FirstName;
public string FirstName
{
get { return _FirstName; }
set { _FirstName = value; }
}
public Person(string LastName, string FirstName)
{
this.LastName = LastName;
this.FirstName = FirstName;
}
}
Possible approaches
There's basically three approaches to working out a solution:
- Addding another property to the class that provides the data; for our Person class, this could be a LastFirstName prop, returning this.LastName + " " + this.FirstName
- If you're using a database (with or without ORM), either have the SELECT return the concatenated field or, if your DB is capable of it, add a computed column (i.e. as feasible with SQL Server for ages)
- Adding a converter that concatenates the fields
So, what approach would win a prize for simplest, best, nicest? It depends, of course. 
FWIW, I tend to find generic approaches whereever possible. That having been said, I dislike the another property in my data-class approach - simply because I'll have to provide such a property for every class where I need to concatenate fields. The DB-based approach is not even close to practical either - what if I don't have control over the database (this has happened quite a few times).
Alright, the title of the article suggested it - I'll show you how to create a pretty simple converter to do the trick. But why? The converter is a stand-alone class that I can drop into any project and, from there on, use it with whatever fields I need to concatenate. It also allows me to concatenate a bunch of fields (as opposed to only two of them - think of a delimited list).
Enter the IMultiValueConverter interface
I was just about to paste a link to the IMultiValueConverter Interface docs on MSDN, so I looked it up and flew over it. Duh - the article contains quite a few bits that I was to describe here! Besides some error-handling (which of course should be in place!), there's really two tiny bits my converter has that the MSDN samples don't - a) I'm utilizing the parameter argument, allowing to specify the delimiter to be used when concatenating and b) my converter doesn't restrict you to just two fields. Here's the converter's code (note that I stripped off all the comments and the sample XAML - you'll find that in the sample solution (see the bottom of this post for the download-link).
[ValueConversion(typeof(object), typeof(string))]
public class ConcatenateFieldsMultiValueConverter : IMultiValueConverter
{
public object Convert(
object[] values,
Type targetType,
object parameter,
System.Globalization.CultureInfo culture
)
{
string strDelimiter;
StringBuilder sb = new StringBuilder();
if (parameter != null)
{
//Use the passed delimiter.
strDelimiter = parameter.ToString();
}
else
{
//Use the default delimiter.
strDelimiter = ", ";
}
//Concatenate all fields
foreach (object value in values)
{
if (value != null && value.ToString().Trim().Length > 0)
{
if (sb.Length > 0) sb.Append(strDelimiter);
sb.Append(value.ToString());
}
}
return sb.ToString();
}
public object[] ConvertBack(
object value,
Type[] targetTypes,
object parameter,
System.Globalization.CultureInfo culture
)
{
throw new NotImplementedException("ConcatenateFieldsMultiValueConverter cannot convert back (bug)!");
}
}
Using the converter with your XAML
Let's see how to actually make use of the converter in XAML. First of all, since we reference a class within the project from XAML, we need to add the underlying namespace to the window:
<Window x:Class="CS.DemoCS"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CS"
Title="DemoVB" Height="300" Width="300">
(...)
From here on, we can now refer to classes in the project with the <local:[class]> syntax. The converter will furthermore need to be added as a resource. While this resource could be placed into the <[Control].Resources> section, I prefer to define my resources on the window-level, this way I only need to reference them once, so here goes:
<Window.Resources>
<local:ConcatenateFieldsMultiValueConverter x:Key="mvc"/>
</Window.Resources>
From this point on, we can refer to the converter by its key mvc. Here's the complete XAML of the window you'll find in the sample solution:
<Window x:Class="CS.DemoCS"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CS"
Title="DemoVB" Height="300" Width="300">
<Window.Resources>
<local:ConcatenateFieldsMultiValueConverter x:Key="mvc"/>
</Window.Resources>
<ListBox ItemsSource="{Binding PersonList}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource mvc}"
ConverterParameter=", ">
<Binding Path="LastName"/>
<Binding Path="FirstName"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Window>
As you can see in the XAML above, the TextBlock I'm using as the ListBox'es DataTemplate uses a MultiBinding in order to pass the field-bindings as well as the delimiter to the converter which, in turn, will return the concatenated result.
If you wanted the ListBox to show its items as in "FirstName LastName", you'd only have to exchange the two bindings (having FirstName appear first) and change the ConverterParameter from ", " to " ".
For the sake of completeness, here's the code-behind of the window, so you can see the source of the bindings:
using System.Collections.Generic;
namespace CS
{
public partial class DemoCS
{
//The source for the ListBox
private List<Person> _lstPersons;
public List<Person> PersonList
{
get { return _lstPersons; }
set { _lstPersons = value; }
}
public DemoCS()
{
InitializeComponent();
//Create the list of persons and add some entries for display
_lstPersons = new List<Person>();
_lstPersons.Add(new Person("Davolio", "Nancy"));
_lstPersons.Add(new Person("Fuller", "Andrew"));
_lstPersons.Add(new Person("Leverling", "Janet"));
_lstPersons.Add(new Person("Peacock", "Margaret"));
_lstPersons.Add(new Person("Buchanan", "Steven"));
_lstPersons.Add(new Person("Suyama", "Michael"));
_lstPersons.Add(new Person("King", "Robert"));
_lstPersons.Add(new Person("Callahan", "Laura"));
_lstPersons.Add(new Person("Dodsworth", "Anne"));
this.DataContext = this;
}
}
}
And here's the result of the sample window

The converter bonus
Another major advantage of the converter over any other alternative I can think of is the fact that, using a converter, we'll make use of the terrific data-binding possibilities WPF has to offer! That is, as a result, the converter's result can easily be used in scenarios where the fields that are being concatenated are changed by means of a different control on the same window. For instance, in my data-centric apps I often have windows in which I'm presenting a list of records, the selected item being the one loaded into detail-controls on the same window. Suppose we had a window with the ListBox control (containing list of Person-classes) on the left and one TextBox for each the LastName and FirstName property on the right - when the user selects an entry in the ListBox, the TextBoxes will allow to edit that entry. If you're using the converter, you'll see the data-binding magic kick in - changing i.e. the LastName in the TextBox would thus change it in the ListBox as well (provided INotifyPropertyChanged was properly implemented).
But wait!
Today (April 21st 2010), Richard posted a comment that was a real eye-opener. As it seems, the Converter actually isn't required at all. That is, utilizing the MultiBinding's StringFormat really makes the Converter obsolete:
<MultiBinding StringFormat="{}{0}, {1}">
<Binding Path="LastName"/>
<Binding Path="FirstName"/>
</MultiBinding>
Although I haven't tested this with lists that are being changed by other means, I'm pretty certain that the data-binding would work equally well for this. Another lesson learned!
Make sure you visit Lester's blog about the WPF 3.5 SP1 feature: StringFormat - wish I had come over that post earlier (again, thanks go out to Richard for mentioning this - see the comments).
Edit (April 30th 2010)
I came back to revisit this today, in an application I'm working on at present. I must admit I still feel stupid for not knowing about the StringFormat mentioned above. However, there actually still is the need for the Converter. That is, while the StringFormat does the job for the data presented in this post, it won't if your persons' names do not necessarily require users to enter a first name. In this case, the StringFormat will always print the comma (or whatever delimiter is being used) if you print your name-fields as in LastName, FirstName, even if there is no value for the FirstName field. That being said, I'm still favoring the Converter-approach (does that save my neck?). 
The sample solution
If you still want to download the code, I’ve created a sample solution that contains everything discussed here with one project for each C# and VB.
Download: ConcatenateConverter.zip (26.30 kb)
Location: PostList