Ha Pham
Ha Pham

Reputation: 413

WPF ComboboxItem binding

I want to learn WPF programming. I want to know binding the gender of staff to the ComboBox:

class Staff {
    public int Gender {get; set;}
}

class ViewModel {
    private Staff _staff
    public Staff Staff {
        get {return _staff;}
        set {
            _staff = value;
            RaisePropertyChangedEvent("Staff");
        }
    }
}

<ComboBox SelectedItem="{Binding Staff.Gender, Converter={StaticResource GenderConverter}}">
    <ComboBoxItem IsSelected="True" Content="{StaticResource strGenderMale}"/>
    <ComboBoxItem Content="{StaticResource strGenderFemale}"/>
    <ComboBoxItem  Content="{StaticResource strGenderOther}"/>
</ComboBox>

GenderConverter is my customized Converter to convert int <-> string (0: male, 1: female, 2: other)

public class IntegerToGenderConverter : IValueConverter {
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
        if (value is int) {
            if ((int)value == MyConstants.GENDER_MALE) { //GENDER_MALE is 1
                return MyConstants.GENDER_MALE_STR; //GENDER_MALE_STR is the string: "Male"
            }
            if ((int)value == MyConstants.GENDER_FEMALE) {
                return MyConstants.GENDER_FEMALE_STR;
            }
        }
        return MyConstants.GENDER_OTHER_STR;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
        switch (value.ToString()) {
            case MyConstants.GENDER_MALE_STR:
                return MyConstants.GENDER_MALE;
            case MyConstants.GENDER_FEMALE_STR:
                return MyConstants.GENDER_FEMALE;
            default:
                return MyConstants.GENDER_OTHER;
        }
    }
}

When i run the application, the staff is not null (everything else (such as name, date of birth...) is bound well except Gender :(

Edit:

When I created a List Genders and bound it to the ComboBox's property ItemsSource instead of using tags, it worked well. Why???

Upvotes: 3

Views: 4343

Answers (1)

Clemens
Clemens

Reputation: 128146

A ComboBox uses ComboBoxItem as item type when you explicitly add them like

<ComboBox>
    <ComboBoxItem Content="..."/>
    ...
</ComboBox>

This means that the SelectedItem property returns a ComboBoxItem, which is then passed to your converter. However, your converter does not expect values of type ComboBoxItem.

When you add integers - as in your bound Genders list - the item type is int, which you successfully handled in your converter. In this case the ComboBox class creates and uses ComboBoxItems only internally.

This is a common behaviour in all WPF controls that are derived from ItemSource. They use the item type that is provided by the user.


That said, you would usually use an enumeration type for your Gender property:

public enum Gender
{
    Male, Female, Other
}

public class Staff
{
    public Gender Gender { get; set; }
}

Then you would add Gender values to your ComboBox and bind the SelectedItem without a converter:

<ComboBox SelectedItem="{Binding Staff.Gender}">
    <local:Gender>Male</local:Gender>
    <local:Gender>Female</local:Gender>
    <local:Gender>Other</local:Gender>
</ComboBox>

where local is a XAML namespace declaration of the C# namespace that contains the Gender type.

Upvotes: 1

Related Questions