user2453973
user2453973

Reputation: 309

Multiple ComboBox.DisplayMemberPath options?

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

Answers (4)

Robin
Robin

Reputation: 1

Or you simply override the ToString method in your class e.g.

    public override string ToString()
    {
        return Name + " " + Age;
    }

Upvotes: 0

Rohit Vats
Rohit Vats

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

Noctis
Noctis

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

Sajeetharan
Sajeetharan

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

Related Questions