2

In my WPF UserControl I need to bind an Enum on a ComboBox. This enum is declared locally:

public partial class ViewerDataConfiguration : UserControl
{
    private ViewerDataConfigurationViewModel PageViewModel;
    public Visibility IsParametriSelected { get; set; }

    public IEnumerable<eDatoAlarmMode> EnumAlarmModes {
        get
        {
            return Enum.GetValues(typeof(eDatoAlarmMode)).Cast<eDatoAlarmMode>();
        }
    }

On the main Grid, where there is a collection bound, I defined a ComboBox as follows:

<TextBox Grid.Column="16" Text="{Binding ConfigObject.Edit.Source}" Style="{StaticResource txtDataStyle2}" Width="30" Visibility="{Binding ConfigObject.Edit, Converter={StaticResource ListaValoriVisibilityConverter}}" HorizontalAlignment="Stretch" TextChanged="Data_TextChanged" />
<Label Grid.Column="17" Content="AlarmMode" Style="{StaticResource labelStyle2}" />
<ComboBox Grid.Column="18" Width="30"
          ItemsSource="{Binding Path=EnumAlarmModes, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:ViewerDataConfiguration}}"
          DisplayMemberPath="Value"
          SelectedValuePath="Value" Style="{StaticResource comboUsersStyle}" />

Basically seems that my IEnumerable is not bound correctly. I see the elements but they're blank. Any hint?

1 Answer 1

3

You are using DisplayMemberPath and SelectedValuePath attributes, but your collection item type is just a simple string, and want to use this entire instance directly, so you should remove these attributes and it should work as expected.

You also need to change the field to a property as data binding works only on properties, not class fields (although x:Bind in UWP no longer has this limitation):

  public IEnumerable<AlarmMode> EnumAlarmModes
    {
        get
        {
            return Enum.GetValues(typeof(AlarmMode)).Cast<AlarmMode>();
        }
    }

If you want to display enum values instead of names, create a value converter:

public class EnumValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (int)value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

And then use it in the ItemTemplate:

<ComboBox Grid.Column="18" Width="100"

    ItemsSource="{Binding Path=EnumAlarmModes}">
    <ComboBox.Resources>
        <local:EnumValueConverter x:Key="EnumValueConverter" />
    </ComboBox.Resources>
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Converter={StaticResource EnumValueConverter}}" />
        </DataTemplate>
    </ComboBox.ItemTemplate>     
</ComboBox>

For this to work you also have to add a xmlns:local declaration to your Window:

xmlns:local="clr-namespace:NamespaceOfConverter"
Sign up to request clarification or add additional context in comments.

5 Comments

I slightly modified the code, as in effect a IEnumerable of string is not usefu as I need to bind name and value in the combobox. So the property now is: public IEnumerable<eDatoAlarmMode> EnumAlarmModes { get { return Enum.GetValues(typeof(eDatoAlarmMode)).Cast<eDatoAlarmMode>(); } } And I restored the DisplayMemberPath="Value" SelectedValuePath="Name"
Nope... my enum contains 3 items, I only see 3 empty items binded in the combobox
Remove the DisplayMemberPath and SelectedValuePath attributes, it works well without them.
Also if you want to display enum value instead of name, I have updated my answer with the solution.
Awesome :-) . Happy coding!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.