ListBox (Selector) and SelectedValuePath / SelectedValue

Topics: Conventions
Sep 6, 2011 at 11:25 AM

Hi,

I really like Caliburn Micro! Great work!

I want to share an improvement: (Maybe for a later version? - Or just use my code below.)

To make localization easier I use a class NamedItem with two properties:

string Name;
object Value; (or generic T value)

My XAML for a ListBox looks like this:

<ListBox Name="..." DisplayMemberPath="Name" SelectedValuePath="Value">

When setting up the ItemsSource I am concerned about localization, so I need to create NamedItem intances.

The rest of my ViewModel does not care about localization and I would like to use the "real" value instead of the NamedItem instance.

Caliburn binds SelectedItem - unfortunately it is the NamedItem instance even though I set SelectedValuePath in XAML.

I would like to bind to SelectedValue instead.

So I changed the convention:

            // Change convention for Selector
            ConventionManager.GetElementConvention(typeof(Selector))
                .ApplyBinding = (viewModelType, path, property, element, convention) =>
                {
                    if (!ConventionManager.SetBinding(viewModelType, path, property, element, convention))
                        return false;

                    ConventionManager.ConfigureSelectedItem(element,
                                                            !string.IsNullOrEmpty(((Selector)element).SelectedValuePath) ?
                                                                Selector.SelectedValueProperty : Selector.SelectedItemProperty,
                                                            viewModelType, path);
                    ConventionManager.ApplyItemTemplate((ItemsControl)element, property);

                    return true;
                };

It's the Caliburn Micro convention with one change: I check if SelectedValuePath is set and if it is I bind to SelectedValueProperty instead of SelectedItemProperty.

This change makes the rest of my ViewModel easier. I.e. I can use SelectedXyz instead of SelectedXyz.Value when checking the selected value of the list box.

I hope it helps...

Regards,

Peter