これはうまくいくはずです。はMarkupExtension
、与えられた列挙型の値を列挙します。それを取得したら、 のようItemsControl
な適切なサブクラスで好きなことを行うことができますListBox
。私は MultiDataConverter も作成しました。これは、単一の列挙フラグを取り、それが一連のフラグに含まれているかどうかを確認します。そのため、トリガーを作成して、ほぼすべてのことを行うことができます。
値を常に表示し、(たとえば) 項目 DataTemplate のチェックボックスによってフラグのセットに含めたり除外したりしたい場合は、別の 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);
}
}
}
...そして XAML では、コレクションを表示するすべてのコントロールが、適切なテンプレートで表示できます。ValueConverters
列挙値自体を使用して、より多くのことを行うように書くことができます。
<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>
そして、指定された列挙値が一連のフラグの 1 つであるかどうかを確認する MultiDataConverter を次に示します。
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();
}
}