2
<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]アプリ内の他の列挙型に適用したいので、このボイラー #plate コードを何度も何度も書きたくありません。助言がありますか?ありがとう!

4

1 に答える 1

2

これはうまくいくはずです。は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();
    }
}
于 2016-03-29T19:51:56.167 に答える