Reputation: 309
I am binding a collection of objects to a ComboBox
. What I want to achieve is a combobox that displays two properties of my object. However, I haven't figured out how to make a combobox display multiple DisplayMemberPaths
. Is this possible?
This is how I'm currently setting up my Binding, and setting the DisplayMemberPath
:
Binding comboBinding = new Binding();
comboBinding.Source = squad_members; //squad_members is the object collection
BindingOperations.SetBinding(Character_ComboBox, ComboBox.ItemsSourceProperty, comboBinding);
Character_ComboBox.DisplayMemberPath = "Name"; //
//Character_ComboBox.DisplayMemberPath = "Name" + "Age"; //failed attempt
Character_ComboBox.SelectedValuePath = "Name";
Upvotes: 5
Views: 9736
Reputation: 1
Or you simply override the ToString method in your class e.g.
public override string ToString()
{
return Name + " " + Age;
}
Upvotes: 0
Reputation: 81243
First of all you should do the binding in XAML instead of code behind.
You can provide ItemTemplate
and use StringFormat
in MultiBinding
like this:
<ComboBox ItemsSource="{Binding YourCollection}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} - {1}">
<Binding Path="Name"/>
<Binding Path="Age"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
In case you want to do binding still in code behind.
You can omit setting DisplayMemberPath altogether by overriding ToString() method in your underlying source class. Since, internally ToString() gets called if DisplayMemberPath is not provided.
Say you collection is of type List<Person>
, so you can override ToString() on Person class:
public override string ToString()
{
return Name + Age;
}
With this in place, binding will look like this (DisplayMemberPath not needed)
Binding comboBinding = new Binding();
comboBinding.Source = squad_members; //squad_members is the object collection
BindingOperations.SetBinding(Character_ComboBox,
ComboBox.ItemsSourceProperty, comboBinding);
Upvotes: 13
Reputation: 11763
In addition to the other answer, you can either have a property that returns what you want, or better, a converter that will do the job for you.
Prop:
public int First {get; set;}
public int Second {get; set;}
public int BindToThis {get{return First+Second;}}
Converter: See example In this MSDN page .
Mainly along the lines:
<TextBlock Name="textBox2" DataContext="{StaticResource NameListData}">
<TextBlock.Text>
<MultiBinding Converter="{StaticResource myNameConverter}"
ConverterParameter="FormatLastFirst">
<Binding Path="FirstName"/>
<Binding Path="LastName"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
and:
public class NameConverter : IMultiValueConverter
{
public object Convert( object[] values
, Type targetType
, object parameter
, CultureInfo culture )
{
string name;
switch ((string)parameter)
{
case "FormatLastFirst":
name = values[1] + ", " + values[0];
break;
case "FormatNormal":
default:
name = values[0] + " " + values[1];
break;
}
return name;
}
// public object[] ConvertBack...
}
Upvotes: 1
Reputation: 222572
Use an ItemTemplate of your ComboBox,Use many TextBlock, as many columns you need. Something like this,
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Width="50" Text="{Binding Path=Name}" />
<TextBlock Width="50" Text="{Binding Path=Age}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
Upvotes: 3