This should work. The MarkupExtension
enumerates the values of any enum type you give it, and once you've got that, you can do anything you like in an ItemsControl
or any appropriate subclass like ListBox
. I've written a MultiDataConverter as well, which takes a single enum flag and checks to see if it's included in a set of flags. Given that, you can write a trigger to do just about anything.
If you want the values to be always visible and be included/excluded from the set of flags by (for example) a checkbox in the item DataTemplate, that would be another MultiDataConverter.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Markup;
namespace EdTest
{
[Flags]
public enum TestEnum
{
Foo = 1 << 0,
Bar = 1 << 1,
Baz = 1 << 2,
Ping = 1 << 3,
Pong = 1 << 4,
Hoop = 1 << 5,
Floop = 1 << 6
};
public class EnumEnumerator : MarkupExtension
{
public EnumEnumerator(Type type)
{
_type = type;
}
private Type _type;
public override object ProvideValue(IServiceProvider serviceProvider)
{
return Enum.GetValues(_type);
}
}
}
...and in the XAML, any control that displays collections can display it in any appropriate template. You could write ValueConverters
to do more stuff with the enum values themselves.
<ItemsControl
xmlns:test="clr-namespace:EdTest"
ItemsSource="{test:EnumEnumerator test:TestEnum}"
>
<ItemsControl.Resources>
<test:FlagCheckConverter x:Key="FlagChecker" />
</ItemsControl.Resources>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border
x:Name="Border"
Padding="6"
Width="80"
Height="60"
BorderBrush="SteelBlue"
BorderThickness="1,1,0,0"
>
<ContentControl Content="{Binding}" />
</Border>
<DataTemplate.Triggers>
<DataTrigger Value="False">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource FlagChecker}">
<!-- The DataContext value - a single enum value -->
<Binding />
<Binding
Path="DataContext.TestFlags"
RelativeSource="{RelativeSource AncestorType=ItemsControl}"
/>
</MultiBinding>
</DataTrigger.Binding>
<Setter TargetName="Border" Property="Visibility" Value="Collapsed" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel
Orientation="Horizontal"
/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
And here's the MultiDataConverter that checks to see if a given enum value is one of a set of flags:
public class FlagCheckConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType,
object parameter, CultureInfo culture)
{
var checkValue = values[0];
var flags = values[1];
if (checkValue is Enum && flags is Enum)
{
return ((Enum)flags).HasFlag((Enum)checkValue);
}
return (object)false;
}
public object[] ConvertBack(object value, Type[] targetTypes,
object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}