How to use MultiBinding in a WPF ComboBox

28,204

You're close! What you want to do though is ComboBox.ItemTemplate, not SelectedValue. Prepare for some XAML hell.

<ComboBox.ItemTemplate>
    <DataTemplate>
        <TextBlock>
            <TextBlock.Text>
                <MultiBinding Converter="{StaticResource StringsToFillNameMultiConverter}">
                    <Binding Path="EmpFirstName" />
                    <Binding Path="EmpLastName" />
                </MultiBinding>
            </TextBlock.Text>
        </TextBlock>
    </DataTemplate>
</ComboBox.ItemTemplate>

Also, if I recall correctly, you don't need to create your own converter if you're just formatting strings. I think you can do the following (someone please correct me if I'm wrong.)

<!-- "Last, First" -->
<MultiBinding StringFormat="{}{1}, {0}">
    <Binding Path="EmpFirstName" />
    <Binding Path="EmpLastName" />
</MultiBinding>
Share:
28,204
Mike B
Author by

Mike B

I am a small business owner that has rediscovered a love of programming. 20 years ago I was a moderately skilled programmer, after a 20 year break I am, once again, a newbie. My programming background was in the 80's in BASIC, 6502/8088 Assy and a spattering of PASCAL, FORTRAN etc.. I had no exposure whatsoever to OOP until I decided to learn C# on my own a few years ago. I do have a background in electronics including digital design and theory, again from the 80s. My goal is to build a series of small aps to enable employees to work more efficiently and to make certain tasks easier for them. Unfortunately I am finding doing so, while enjoyable, a bit frustrating in a vacuum and so I turn to Stack Overflow as my mentor :-)

Updated on February 11, 2020

Comments

  • Mike B
    Mike B over 4 years

    This is driving me NUTS!!!

    I have a ComboBox used to filter a query by employee which works fine but only displays the employees first name. I want to use a MultiValueConverter to display the employees full name (This would be less urgent if we did not have 2 Mikes and 2 Daves)

    Below is my working code and the IMultiValueConverter Class (With unnecessary formatting trimmed out for brevity). I have tried everything I can think of to get the MultiConverter to work but I have had no luck.

    <ComboBox ItemsSource="{Binding Path=EmployeesFilter}" 
                           DisplayMemberPath="EmpFirstName"
                           SelectedValue="{Binding Path=EmployeeToShow, Mode=TwoWay}"/>
    

    The ViewModel Properties it is bound to:

    // This collection is used to populate the Employee Filter ComboBox
    private ObservableCollection<Employee> employeesFilter;
    public ObservableCollection<Employee> EmployeesFilter
    {
        get {
                return employeesFilter;
            }
        set {
            if (employeesFilter != value)
            {
                employeesFilter = value;
                OnPropertyChanged("EmployeesFilter");
            }
        }
    }
    
    // This property is TwoWay bound to the EmployeeFilters SelectedValue
    private Employee employeeToShow;
    public Employee EmployeeToShow
    {
        get {
                return employeeToShow;
            }
        set {
            if (employeeToShow != value)
            {
                employeeToShow = value;
                OnPropertyChanged("EmployeeToShow");
                QueryIssues(); // Requery with new employee filter
            }
        }
    }
    

    The IMultiValueConverter:

    class StringsToFullNameMultiConverter : IMultiValueConverter
    {
        public object Convert(object[] values, 
                              Type targetType, 
                              object parameter, 
                              System.Globalization.CultureInfo culture)
        {
            // I added this because I kept getting DependecyProperty.UnsetValue 
            // Passed in as the program initializes
            if (values[0] as string != null)
            {
                string firstName = (string)values[0];
                string lastName = (string)values[1];
                string fullName = firstName + " " + lastName;
                return fullName;
            }
            return null;
        }
    
        public object[] ConvertBack(object value, 
                                    Type[] targetTypes, 
                                    object parameter, 
                                    System.Globalization.CultureInfo culture)
        {
            return null; 
        }
    }
    

    I tried a lot of different things but basically am using the following in the ComboBox

    <ComboBox.SelectedValue>
         <MultiBinding Converter="{StaticResource StringsToFullNameMultiConverter}" 
                       Mode="OneWay" > 
               <Binding Path="EmpFirstName" />
               <Binding Path="EmpLastName"/>
         </MultiBinding>
    </ComboBox.SelectedValue>
    

    As it stands now the converter is called when the program initializes with the values set to DependencyProperty.UnsetValue. after that it is never called again, even when you select a name from the box. The names are still displayed as a first name.

    Thanks for any help or pointers to good tutorials/samples you can provide. All the ones I keep finding on the web are for textboxes and I can use them just fine all day.