I have a composite collection which consists of:
- combobox item with content 'Select a vendor'
- collection container with collection of Vendor objects, bound to a combobox
cmbVendor
When a vendor is selected from the combobox, the ToString()
method is called.
However, I want to display the value of the property Name
of the selected Vendor object.
Setting the combobox property DisplayMemberPath='Name'
works but then the 'Select a vendor' is not shown anymore on load, which is not desired.
Notes:
- sometimes a Vendor object is chosen from code-behind
- I can not override
ToString()
method of a Vendor object for other reasons
Any suggestions?
XAML
<UserControl.Resources>
<converters:VendorConverter x:Key='VendorConverter' />
<CollectionViewSource x:Key='VendorsCollection'
Source='{Binding Vendors}'>
</CollectionViewSource>
</UserControl.Resources>
<Grid>
<ComboBox Name='cmbVendor'
SelectedItem='{Binding Vendor, Converter={StaticResource VendorConverter}, Mode=TwoWay}'
IsSynchronizedWithCurrentItem='True'
IsEditable='True'
Width='{DynamicResource VendorCmbWidth}'>
<!--Make sure "Select a vendor" is selected-->
<i:Interaction.Behaviors>
<behaviour:SelectFirstItemBehavior />
</i:Interaction.Behaviors>
<ComboBox.Resources>
<DataTemplate DataType='{x:Type objects:Vendor}'>
<StackPanel Orientation='Horizontal'>
<TextBlock Text='{Binding Name}' />
</StackPanel>
</DataTemplate>
<DataTemplate DataType='{x:Type system:String}'>
<StackPanel Orientation='Horizontal'>
<TextBlock Text='{Binding }' />
</StackPanel>
</DataTemplate>
</ComboBox.Resources>
<ComboBox.ItemsSource>
<CompositeCollection>
<ComboBoxItem Content='Select a vendor' />
<CollectionContainer Collection='{Binding Source={StaticResource VendorsCollection}}' />
</CompositeCollection>
</ComboBox.ItemsSource>
</ComboBox>
</Grid>
</UserControl>
VendorConverter
internal class VendorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var vendor = value as Vendor;
if (vendor != null)
{
return vendor;
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var comboboxItem = value as ComboBoxItem;
if (comboboxItem != null)
{
return null;
}
var vendor = value as Vendor;
if (vendor != null)
{
return vendor;
}
return null;
}
}
Behaviors
internal class SelectFirstItemBehavior : Behavior<ComboBox>
{
protected override void OnAttached()
{
AssociatedObject.SelectionChanged += AssociatedObject_SelectionChanged;
}
protected override void OnDetaching()
{
AssociatedObject.SelectionChanged -= AssociatedObject_SelectionChanged;
base.OnDetaching();
}
private void AssociatedObject_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var combobox = sender as ComboBox;
if (combobox != null && combobox.SelectedIndex == -1)
{
combobox.SelectedIndex = 0;
}
}
}