C# – WPF Data Binding and IValueConverter

cconverterdata-bindingwpf

Why is it that when I use a converter in my binding expression in WPF, the value is not updated when the data is updated.

I have a simple Person data model:

class Person : INotifyPropertyChanged
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

My binding expression looks like this:

<TextBlock Text="{Binding Converter={StaticResource personNameConverter}" />

My converter looks like this:

class PersonNameConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        Person p = value as Person;
        return p.FirstName + " " + p.LastName;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

If I bind the data without a converter it works great:

<TextBlock Text="{Binding Path=FirstName}" />
<TextBlock Text="{Binding Path=LastName}" />

What am I missing?

EDIT:
Just to clarify a few things, both Joel and Alan are correct regarding the INotifyPropertyChanged interface that needs to be implemented. In reality I do actually implement it but it still doesn't work.

I can't use multiple TextBlock elements because I'm trying to bind the Window Title to the full name, and the Window Title does not take a template.

Finally, it is an option to add a compound property "FullName" and bind to it, but I'm still wondering why updating does not happen when the binding uses a converter. Even when I put a break point in the converter code, the debugger just doesn't get there when an update is done to the underlying data 🙁

Thanks,
Uri

Best Answer

You can also use a MultiBinding.. Bind to the Person object, the FirstName and LastName. That way, the value gets updated as soon as FirstName or LastName throws the property changed event.

<MultiBinding Converter="{IMultiValueConverter goes here..}">
    <Binding />
    <Binding Path="FirstName" />
    <Binding Path="LastName" />
</MultiBinding>

Or if you only use the FirstName and LastName, strip the Person object from the binding to something like this:

<MultiBinding Converter="{IMultiValueConverter goes here..}">
    <Binding Path="FirstName" />
    <Binding Path="LastName" />
</MultiBinding>

And the MultiValueConverter looks like this:

class PersonNameConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
            return values[0].ToString() + " " + values[1].ToString();
    }

    public object ConvertBack(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
            throw new NotImplementedException();
    }
}

But of course, the selected answer works as well, but a MultiBinding works more elegantly...

Related Topic