[英]How to make a generic switch for [Flags] enums in WPF?
<Grid Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="4">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="DayButtons"/>
<!-- and so on-->
</Grid.ColumnDefinitions>
<ToggleButton Grid.Column="0" IsChecked="{Binding blah blah blah Converter=Whatever, ConverterParameter={x: Static TooFreakingLong}">Monday</ToggleButton>
<!-- and so on -->
</Grid>
因此,我已经定义了一个星期几的枚举,尽管我可以制作一个简单的表格来显示一周中的所有天数并随意切换(想想一个周期性的日历日应用程序)。 但是,我想将此模式应用到我的应用程序中的其他[Flags]
枚举,并且我不想一遍又一遍地编写所有这些锅炉代码代码。 有什么建议么? 谢谢!
这应该工作。 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>
这是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();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.