MenuFlyout の内部に下記のように ToggleMenuFlyoutItem を配置すると選択式のメニューとして表示できます
<AppBarButton Label="ネコのえさ"> <AppBarButton.Icon> <PathIcon HorizontalAlignment="Center" VerticalAlignment="Center" Data="M0,16.0044549486488L30.0405913920894,16.0044549486488 ~ 中略 ~ " /> </AppBarButton.Icon> <AppBarButton.Flyout> <MenuFlyout> <ToggleMenuFlyoutItem Padding="20,5,10,6" Text="まぐろ" /> <ToggleMenuFlyoutItem Padding="20,5,10,6" Text="かつお" /> <ToggleMenuFlyoutItem Padding="20,5,10,6" Text="ささみ" /> <ToggleMenuFlyoutItem Padding="20,5,10,6" Text="カニカマ" /> <ToggleMenuFlyoutItem Padding="20,5,10,6" Text="ビーフ" /> </MenuFlyout> </AppBarButton.Flyout> </AppBarButton>
ただ、この ToggleMenuFlyoutItem は複数選択も選択解除もできてしまい、ラジオボタンのように単一選択させることができません
そこで RagioButton の動作をする ToggleMenuFlyoutItem 風コントロールを作ってみます
まずは VisualStudio の「追加」-「新しい項目」から「テンプレートコントロール」を選びます
「RadioMenuItem」という名前で作成し、追加されたクラスの継承元を「RadioButton」に変更し、Text の依存関係プロパティを追加します
/// <summary> /// ラジオボタン風メニューアイテム /// </summary> public sealed class RadioMenuItem : RadioButton { /// <summary> /// Text の依存関係プロパティ /// </summary> public static readonly DependencyProperty TextProperty = DependencyProperty.Register( "Text", typeof(string), typeof(RadioMenuItem), new PropertyMetadata(null)); /// <summary> /// Text プロパティ /// </summary> public string Text { get { return (string)this.GetValue(TextProperty); } set { this.SetValue(TextProperty, value); } } /// <summary> /// コンストラクタ /// </summary> public RadioMenuItem() { this.DefaultStyleKey = typeof(RadioMenuItem); } }
その後、Themes フォルダ配下に Generic.xaml ができており、RadioMenuItem のスタイルができているはずなので、下記のように中身を ToggleMenuFlyoutItem のデフォルトスタイルとそっくり差し替えて、ControlTemplate の TargetType だけ RadioMenuItem に変更します
※デフォルトスタイルの探し方は デフォルトのデザインテーマ定義ファイル - しっぽを追いかけて で紹介しているのでご参考ください
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ctrl="using:RadioMenuItemSample.Controls"> <Style TargetType="ctrl:RadioMenuItem"> <Setter Property="Background" Value="Transparent" /> <Setter Property="Padding" Value="{ThemeResource MenuFlyoutItemThemePadding}" /> <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" /> <Setter Property="FontWeight" Value="SemiBold" /> <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" /> <Setter Property="HorizontalContentAlignment" Value="Stretch" /> <Setter Property="VerticalContentAlignment" Value="Center" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ctrl:RadioMenuItem"> <Border x:Name="LayoutRoot" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Normal" /> <VisualState x:Name="PointerOver"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="InnerBorder" Storyboard.TargetProperty="Background"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource MenuFlyoutItemPointerOverBackgroundThemeBrush}" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextBlock" Storyboard.TargetProperty="Foreground"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource MenuFlyoutItemPointerOverForegroundThemeBrush}" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckGlyph" Storyboard.TargetProperty="Fill"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource MenuFlyoutItemPointerOverForegroundThemeBrush}" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="Pressed"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="InnerBorder" Storyboard.TargetProperty="Background"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource MenuFlyoutItemPressedBackgroundThemeBrush}" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextBlock" Storyboard.TargetProperty="Foreground"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource MenuFlyoutItemPressedForegroundThemeBrush}" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckGlyph" Storyboard.TargetProperty="Fill"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource MenuFlyoutItemPressedForegroundThemeBrush}" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="Disabled"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextBlock" Storyboard.TargetProperty="Foreground"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource MenuFlyoutItemDisabledForegroundThemeBrush}" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckGlyph" Storyboard.TargetProperty="Fill"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource MenuFlyoutItemDisabledForegroundThemeBrush}" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> </VisualStateGroup> <VisualStateGroup x:Name="FocusStates"> <VisualState x:Name="Focused"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="Background"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource MenuFlyoutItemFocusedBackgroundThemeBrush}" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextBlock" Storyboard.TargetProperty="Foreground"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource MenuFlyoutItemFocusedForegroundThemeBrush}" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckGlyph" Storyboard.TargetProperty="Fill"> <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource MenuFlyoutItemFocusedForegroundThemeBrush}" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="Unfocused" /> <VisualState x:Name="PointerFocused" /> </VisualStateGroup> <VisualStateGroup x:Name="CheckStates"> <VisualState x:Name="Unchecked" /> <VisualState x:Name="Checked"> <Storyboard> <DoubleAnimation Storyboard.TargetName="CheckGlyph" Storyboard.TargetProperty="Opacity" To="1" Duration="0" /> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <Border x:Name="InnerBorder"> <Grid Margin="{TemplateBinding Padding}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="*" /> </Grid.ColumnDefinitions> <Path x:Name="CheckGlyph" Margin="0,0,10,0" Data="F1 M 0,58 L 2,56 L 6,60 L 13,51 L 15,53 L 6,64 z" Fill="{TemplateBinding Foreground}" Height="14" Stretch="Fill" Width="16" Opacity="0" FlowDirection="LeftToRight" /> <TextBlock x:Name="TextBlock" Grid.Column="1" Text="{TemplateBinding Text}" TextTrimming="CharacterEllipsis" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" /> </Grid> </Border> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>
あとは画面の XAML の方を下記のような感じに書き換えて
<AppBarButton Label="ネコのえさ"> <AppBarButton.Icon> <PathIcon HorizontalAlignment="Center" VerticalAlignment="Center" Data="M0,16.0044549486488L30.0405913920894,16.0044549486488 ~中略~ " /> </AppBarButton.Icon> <AppBarButton.Flyout> <Flyout> <StackPanel Margin="-20" Orientation="Vertical"> <ctrl:RadioMenuItem Text="まぐろ" /> <ctrl:RadioMenuItem Text="かつお" /> <ctrl:RadioMenuItem Text="ささみ" /> <ctrl:RadioMenuItem Text="カニカマ" /> <ctrl:RadioMenuItem Text="ビーフ" /> </StackPanel> </Flyout> </AppBarButton.Flyout> </AppBarButton>
実行!
できました!
動作は継承した RadioButton、見た目は Style にコピペした ToggleMenuFlyoutItem がよろしくやってくれるのというわけです