views:

662

answers:

1

Ok, Ive searched the heck out of the Interwebs and can't seem to find this right. I have a ComboBox that is bound to a CollectionViewSource of EntityFramework entities. The display is a template that shows the first/last name. The problem is, when an item is selected, the Display of the combobox == the object.ToString() (i.e. MyCompany.Data.Professional) instead of something useful.

I'm sure I am missing a property here. The ri is the UserControl, and the SelectedPhysician is a DependencyProperty of the

            <ComboBox Grid.Column="1" Grid.Row="4"  x:Name="cmbReferringPhys"
                  IsEditable="{Binding IsReadOnly}"
                  ItemsSource="{Binding Source={StaticResource ProfessionalLookup}}"                                           
                  SelectedItem="{Binding ElementName=ri, Path=SelectedPhysian, Mode=TwoWay, UpdateSourceTrigger=LostFocus, NotifyOnValidationError=True, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}"                                            
                  HorizontalAlignment="Left" VerticalAlignment="Top" Height="19.277" Width="300" 
                  IsSynchronizedWithCurrentItem="True"
                  SelectionChanged="ReferringPhy_SelectionChanged" TabIndex="4">
             <ItemsControl.ItemTemplate>
               <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="100" />
                            <ColumnDefinition Width="120" />                                
                        </Grid.ColumnDefinitions>
                        <TextBlock Text="{Binding FirstName}" Grid.Column="0"  Margin="4,0" />
                        <TextBlock Text="{Binding LastName}"  Grid.Column="1" Margin="4,0"/>
                    </Grid>                                                                   
                </DataTemplate>
            </ItemsControl.ItemTemplate>
+2  A: 

You can use a converter (tutorial), but that might be overdoing it a bit. I would recommend using the DisplayMemberPath property of the ComboBox.

To use a converter, you will need to create a converter class (one that implements IValueConverter.) Your code will look something like this:

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        MyCompany.Data.Professional prof = (MyCompany.Data.Professional)value;

        if (prof == null)
        {
            return string.Empty;
        }
        else
        {
            return string.Format("{0} {1}", prof.First, prof.Last); //or however you want to format this
        }  
    }

    // If you'll ever need to convert back from a string to a Professional,
    // implement that logic here
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return null;
    }

In the XAML, you'll do something like this:

    <ComboBox>
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Converter={StaticResource [ConverterClassName]}}" /> 
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>

Edit edit: In this case, I don't think you'll ever need to use ConvertBack, as you'll be able to get at the selected object by casting ComboBox.SelectedItem as a Professional.

oltman
For example, you'd want to use DisplayMemberPath="Data.Professional". Please let me know if this helped you out.
oltman
The problem with the DisplayMemberPath is that the FirstName and LastName are separate fields. What I'd need is something like a DisplayMemberPath Template :) .So, how would you use the converter ( which property on the combobox) ?
Larry R
I didn't have enough space in the comments, but I updated my answer. Hope this helps :)
oltman