1
votes

I have an enum representing possible configurations. (the following is just an example...)

public enum ConfigurationType {
    [Description("Minimal Configuration")]
    Minimal = 0,
    [Description("Standard Configuration")]
    Standard,
    [Description("Premium Configuration")]
    Premium
}

Right now I am binding a property of type ConfigurationType in my class to a ComboBox using a value converter (found here) to display the Description. That works fine. What I would like to do however, is be able to disable the selection of specific enum members on the fly, the result being they would not show up in the ComboBox.

I have tried converting this enum to be a flags enum and then binding to a set of the flags, but didn't get very far. Any pointers on that or other suggestions?

Edit - flags example

When trying to use flags, I changed the enum to:

[Flags]
public enum ConfigurationType {
    [Description("Minimal Configuration")]
    Minimal = 1 << 0,
    [Description("Standard Configuration")]
    Standard = 1 << 1,
    [Description("Premium Configuration")]
    Premium = 1 << 2
}

public ConfigurationType AvailableConfigs = ConfigurationType.Standard | ConfigurationType.Premium;

It actually works for being able to assign bitwise-or'd list of these to a variable such as AvailableConfigs (as shown above), but then the value converter part was the hang-up. I wasn't sure how to implement a value converter to get the description of each flag present in AvailableConfigs, and be able to convert back to a variable (also of ConfigurationType) such as SelectedConfiguration. The setter of SelectedConfiguration would of course enforce only one flag at a time being present.

1
@HiTechMagic Please see edit. - Ethan
That example you are following is only good for the simple "list every enum" case as it returns a complete list of all enums for a given type. You would want to ignore the caching code and filter the enums you want on the fly via reflection. I will add an example... - Gone Coding
@HiTechMagic I'm a newbie with reflection, are you talking about the portion of the code in that converter I linked that actually grabs the description from the properties? Also, is the converterparameter passed in the xaml, and what exactly should be passed? - Ethan
@HiTechMagic thank you so much, I anxiously await your answer :) - Ethan
Forgot you can't bind a ConverterParameter so this needs a slightly different approach. What drives your AvailableConfig setting? Is it static (e.g. can be defined in the XAML) or is it dynamic (driven by app changes)? - Gone Coding

1 Answers

1
votes

If you can define the available options in XAML, you could do this:

in your EnumValuesConverter.cs

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    if (value == null)
        return null;
    else
    {
        if (string.IsNullOrEmpty((string)parameter))
        {
            return EnumValueCache.GetValues(value.GetType());
        }
        return EnumValueCache.GetValues(value.GetType()).Where(x => parameter.ToString().Contains(x.ToString()));
    }
}

And bind with a ConverterParameter used like this:

<ComboBox Height="23" HorizontalAlignment="Left" Margin="25,27,0,0" Name="comboBox1" VerticalAlignment="Top" Width="120" 
          ItemsSource="{Binding MyEnumProperty, Converter={StaticResource enumConverter}, ConverterParameter=Minimal-Standard}"
          SelectedItem="{Binding MyEnumProperty, Mode=TwoWay}"/>

Which will show only the Minimal and Standard options using the ConverterParameter as a simple string filter.

If you need something more dynamic just say so. You can't bind ConverterParameters (unfortunately) so it will need more work.

Dynamic property solution

To do the same thing using an AvailableConfigs property, you would need to implement a MultiBinding solution (which allows you to bind to multiple properties).

The order of the bindings is important as that will be the order they are passed to the converter.

e.g.

<ComboBox Height="23" HorizontalAlignment="Left" Margin="25,27,0,0" Name="comboBox2" VerticalAlignment="Top" Width="120" >
    <ComboBox.ItemsSource>
        <MultiBinding Converter="{StaticResource enumConverter}">
            <Binding Path="MyEnumProperty" />
            <Binding Path="AvailableConfigs" />
        </MultiBinding>
    </ComboBox.ItemsSource>
</ComboBox>

MultiBinding is only part of WPF and not Silverlight so here are a few Silverlight MultiBinding solutions: