ToggleMenuFlyoutItem 点击和选择在 Windows Phone 8.1 应用程序中不起作用

ToggleMenuFlyoutItem tap and selection does not work in Windows Phone 8.1 app

我正在代码中创建 ToggleMenuFlyoutItems 并将它们添加到附加的 MenuFlyout 的项目集合中。

我将每个的 IsTapEnabled 设置为 true,然后将事件处理程序添加到每个的 Tapped 事件,当我点击 MenuFlyoutItem 列表中的其中一个时,点击事件不会被触发。 另外,如果我从代码中设置选中状态,则不可见。

代码如下:

   //XAML code:
   <FlyoutBase.AttachedFlyout>
       <MenuFlyout x:Name="flyout" Placement="Bottom">
       </MenuFlyout>
   </FlyoutBase.AttachedFlyout>

   //C# code:
   //...loop here
   var subItem = new ToggleMenuFlyoutItem();
   subItem.Text = "Test";
   subItem.IsTapEnabled = true;
   subItem.Tapped += SubItem_Tapped;
   subItem.IsChecked = true;
   subItem.IsEnabled = true;

   flyoutMenu.Items.Add(subItem);
   //...loop end here

   //...
   private void SubItem_Tapped(object sender, TappedRoutedEventArgs e)
    {
        Data data = (e.OriginalSource as FrameworkElement).DataContext as Data;

        if (data != null)
        {
            //...
        }
    }

当我按住列表中的一个项目时会出现弹出窗口,该项目的元素(堆栈面板)附加了此弹出窗口,但我无法弄清楚为什么未显示所选状态并且未调用点击事件...

相同的代码在 Windows 10 UWP 应用程序中工作正常,但是...

设置时我是否遗漏了什么? 它不应该以这种方式工作,只能通过在 XAML 文件中添加项目吗?

在代码隐藏中进行设置时,您不会遗漏任何内容。这里的问题是 ToggleMenuFlyoutItem 在 Windows Phone 8.1 上的实现不同于 Windows 8.1 上的实现,也不同于 Windows 10 UWP 应用程序。

首先我们来看Windows8.1应用中ToggleMenuFlyoutItem的样式和模板。

<!-- Default style for Windows.UI.Xaml.Controls.ToggleMenuFlyoutItem -->
<Style TargetType="ToggleMenuFlyoutItem">
    <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="ToggleMenuFlyoutItem">
                <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>

我们可以通过搜索"ToggleMenuFlyoutItem"找到generic.xaml中的默认样式。 "generic.xaml" 文件附带 Windows 8.1 SDK,通常位于 C:\Program Files (x86)\Windows Kits .1\Include\winrt\xaml\design 文件夹。此位置取决于 Windows SDK 安装。

那么对于Windows Phone 8.1中ToggleMenuFlyoutItem的默认样式,我们可以在中的generic.xaml文件中找到]C:\Program Files (x86)\Windows Phone Kits.1\Include\abi\Xaml\Design 文件夹.

<!-- Default style for Windows.UI.Xaml.Controls.ToggleMenuFlyoutItem -->
<Style TargetType="ToggleMenuFlyoutItem">
  <Setter Property="Background" Value="Transparent" />
  <Setter Property="Padding" Value="{ThemeResource MenuFlyoutItemThemePadding}" />
  <Setter Property="HorizontalContentAlignment" Value="Left" />
  <Setter Property="VerticalContentAlignment" Value="Center" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="ToggleMenuFlyoutItem">
        <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" />
              <VisualState x:Name="Pressed">
                <Storyboard>
                  <PointerDownThemeAnimation Storyboard.TargetName="InnerBorder" />
                </Storyboard>
              </VisualState>
              <VisualState x:Name="Disabled">
                <Storyboard>
                  <ObjectAnimationUsingKeyFrames Storyboard.TargetName="TextBlock" Storyboard.TargetProperty="Foreground">
                    <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource MenuFlyoutItemDisabledForegroundThemeBrush}" />
                  </ObjectAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
              <VisualStateGroup.Transitions>
                <VisualTransition From="Pressed" To="PointerOver">
                  <Storyboard>
                    <PointerUpThemeAnimation Storyboard.TargetName="InnerBorder" />
                  </Storyboard>
                </VisualTransition>
                <VisualTransition From="PointerOver" To="Normal">
                  <Storyboard>
                    <PointerUpThemeAnimation Storyboard.TargetName="InnerBorder" />
                  </Storyboard>
                </VisualTransition>
                <VisualTransition From="Pressed" To="Normal">
                  <Storyboard>
                    <PointerUpThemeAnimation Storyboard.TargetName="InnerBorder" />
                  </Storyboard>
                </VisualTransition>
              </VisualStateGroup.Transitions>
            </VisualStateGroup>
          </VisualStateManager.VisualStateGroups>
          <Border x:Name="InnerBorder" Padding="{TemplateBinding Padding}">
            <TextBlock x:Name="TextBlock"
                       Text="{TemplateBinding Text}"
                       HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                       VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
          </Border>
        </Border>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

如果你对比这两种风格,你会发现在Windows Phone 8.1中,模板中只有一个TextBlock。但是在Windows 8.1的模板中,还有一个名为"CheckGlyph"的Path加上"CheckStates" VisualStateGroup用来改变它的可见性。

并且我们可以在Windows10中ToggleMenuFlyoutItem styles and templates找到ToggleMenuFlyoutItem的默认样式和模板。它类似于 Windows 8.1 中的内容,但也有一些差异。

所以选择的状态可以在Windows10,Windows8.1上显示,但在WindowsPhone8.1.

上不能显示

最后,对于ToggleMenuFlyoutItemTapped事件,在WindowsPhone8.1中无法引发。实际上,在 Windows Phone 8.1 应用程序中,MenuFlyoutItemToggleMenuFlyoutItem 的所有 MenuFlyoutItem can not raise this event. To handle the selection of a menu item, we can use Click event 都被替换了。