none
menu内のsubmenuのアイテムフォーカスが外れてしまう RRS feed

  • 質問

  • menu内のsubmenuにスクロールバーを付ける必要があり、以下のようなXAMLを書きました。

    ところが実際に動かすと、サブメニュー(MenuItem1-x)上にマウスカーソルを持っていくとたまに以下現象が発生します。

    一瞬MenuItemにフォーカスが当たるが、すぐにフォーカスが外れる。

    どうもStackPanelの外側にマウスカーソルを持って行き、その後(MenuItem1-x)上にマウスカーソルを持っていくと本問題が発生するようです。

    以下XAMLで問題点、修正点があればご教授頂けると助かります。

    また、menu内のsubmenuにスクロールバーを付ける別の方法があればご教授頂ければと思います。

    宜しくお願い致します。

    以下XAMLコード

      <Menu HorizontalAlignment="Left" Height="100" Width="100" VerticalAlignment="Top">
       <MenuItem Header="MenuItem1" Margin="0">
        <MenuItem Margin="0">
         <MenuItem.Template>
          <ControlTemplate TargetType="{x:Type MenuItem}">
            <ScrollViewer MaxHeight="40">
            <StackPanel IsItemsHost="True"/>
            </ScrollViewer>
          </ControlTemplate>
         </MenuItem.Template>
         <MenuItem Header="MenuItem1-1"/>
         <MenuItem Header="MenuItem1-2"/>
         <MenuItem Header="MenuItem1-3"/>
         <MenuItem Header="MenuItem1-4"/>
        </MenuItem>
       </MenuItem>
      </Menu>

    2010年10月17日 7:39

回答

  • 自己解決したので、その時のSytelを載せておきます。

    MenuItemのスタイルにMenuItemStyle(スタイル名)を設定するとスクロールバー表示が可能となります。

    サブメニューのMaxHeightも指定可能です。

     <Window.Resources>
      <PathGeometry x:Key="Checkmark" Figures="M0,2 L0,4.8 L2.5,7.4 L7.1,2.8 L7.1,0 L2.5,4.6 z"/>
      <ControlTemplate x:Key="{ComponentResourceKey ResourceId=SubmenuItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}" TargetType="{x:Type MenuItem}">
       <Border x:Name="Bd" SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
        <Grid>
         <Grid.ColumnDefinitions>
          <ColumnDefinition SharedSizeGroup="MenuItemIconColumnGroup" MinWidth="17" Width="Auto"/>
          <ColumnDefinition Width="*"/>
          <ColumnDefinition SharedSizeGroup="MenuItemIGTColumnGroup" Width="Auto"/>
          <ColumnDefinition Width="14"/>
         </Grid.ColumnDefinitions>
         <ContentPresenter x:Name="Icon" Margin="4,0,6,0" VerticalAlignment="Center" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" ContentSource="Icon"/>
         <Path x:Name="GlyphPanel" Fill="{TemplateBinding Foreground}" FlowDirection="LeftToRight" Margin="4,0,6,0" VerticalAlignment="Center" Visibility="Hidden" Data="{StaticResource Checkmark}"/>
         <ContentPresenter Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Grid.Column="1" ContentSource="Header" RecognizesAccessKey="True"/>
         <TextBlock x:Name="InputGestureText" Margin="5,2,0,2" Grid.Column="2" DockPanel.Dock="Right" Text="{TemplateBinding InputGestureText}"/>
        </Grid>
       </Border>
       <ControlTemplate.Triggers>
        <Trigger Property="Icon" Value="{x:Null}">
         <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
        </Trigger>
        <Trigger Property="IsChecked" Value="true">
         <Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
         <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
        </Trigger>
        <Trigger Property="IsHighlighted" Value="true">
         <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
         <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
        </Trigger>
        <Trigger Property="IsEnabled" Value="false">
         <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
        </Trigger>
       </ControlTemplate.Triggers>
      </ControlTemplate>
      <Style x:Key="MenuScrollButton" BasedOn="{x:Null}" TargetType="{x:Type RepeatButton}">
       <Setter Property="ClickMode" Value="Hover"/>
       <Setter Property="MinWidth" Value="0"/>
       <Setter Property="MinHeight" Value="0"/>
       <Setter Property="Template">
        <Setter.Value>
         <ControlTemplate TargetType="{x:Type RepeatButton}">
          <DockPanel SnapsToDevicePixels="true" Background="Transparent">
           <Rectangle x:Name="R1" Fill="Transparent" Width="1" DockPanel.Dock="Right"/>
           <Rectangle x:Name="B1" Fill="Transparent" Height="1" DockPanel.Dock="Bottom"/>
           <Rectangle x:Name="L1" Fill="Transparent" Width="1" DockPanel.Dock="Left"/>
           <Rectangle x:Name="T1" Fill="Transparent" Height="1" DockPanel.Dock="Top"/>
           <ContentPresenter x:Name="ContentContainer" HorizontalAlignment="Center" Margin="2,2,2,2" VerticalAlignment="Center"/>
          </DockPanel>
          <ControlTemplate.Triggers>
           <Trigger Property="IsPressed" Value="true">
            <Setter Property="Fill" TargetName="R1" Value="{DynamicResource {x:Static SystemColors.ControlLightLightBrushKey}}"/>
            <Setter Property="Fill" TargetName="B1" Value="{DynamicResource {x:Static SystemColors.ControlLightLightBrushKey}}"/>
            <Setter Property="Fill" TargetName="L1" Value="{DynamicResource {x:Static SystemColors.ControlDarkDarkBrushKey}}"/>
            <Setter Property="Fill" TargetName="T1" Value="{DynamicResource {x:Static SystemColors.ControlDarkDarkBrushKey}}"/>
            <Setter Property="Margin" TargetName="ContentContainer" Value="3,3,1,1"/>
           </Trigger>
          </ControlTemplate.Triggers>
         </ControlTemplate>
        </Setter.Value>
       </Setter>
      </Style>
      <Geometry x:Key="UpArrow">M 0,4 L 3.5,0 L 7,4 Z</Geometry>
      <MenuScrollingVisibilityConverter x:Key="MenuScrollingVisibilityConverter"/>
      <Geometry x:Key="DownArrow">M 0,0 L 3.5,4 L 7,0 Z</Geometry>
      <Style x:Key="{ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}" BasedOn="{x:Null}" TargetType="{x:Type ScrollViewer}">
       <Setter Property="HorizontalScrollBarVisibility" Value="Hidden"/>
       <Setter Property="VerticalScrollBarVisibility" Value="Auto"/>
       <Setter Property="Template">
        <Setter.Value>
         <ControlTemplate TargetType="{x:Type ScrollViewer}">
          <Grid SnapsToDevicePixels="true">
           <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
           </Grid.ColumnDefinitions>
           <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
           </Grid.RowDefinitions>
           <Border Grid.Column="0" Grid.Row="1">
            <ScrollContentPresenter Margin="{TemplateBinding Padding}"/>
           </Border>
           <RepeatButton Style="{StaticResource MenuScrollButton}" Focusable="false" Command="{x:Static ScrollBar.LineUpCommand}" CommandTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}" Grid.Column="0" Grid.Row="0">
            <RepeatButton.Visibility>
             <MultiBinding FallbackValue="Visibility.Collapsed" Converter="{StaticResource MenuScrollingVisibilityConverter}" ConverterParameter="0">
              <Binding Path="ComputedVerticalScrollBarVisibility" RelativeSource="{RelativeSource TemplatedParent}"/>
              <Binding Path="VerticalOffset" RelativeSource="{RelativeSource TemplatedParent}"/>
              <Binding Path="ExtentHeight" RelativeSource="{RelativeSource TemplatedParent}"/>
              <Binding Path="ViewportHeight" RelativeSource="{RelativeSource TemplatedParent}"/>
             </MultiBinding>
            </RepeatButton.Visibility>
            <Path Fill="{DynamicResource {x:Static SystemColors.MenuTextBrushKey}}" Data="{StaticResource UpArrow}"/>
           </RepeatButton>
           <RepeatButton Style="{StaticResource MenuScrollButton}" Focusable="false" Command="{x:Static ScrollBar.LineDownCommand}" CommandTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}" Grid.Column="0" Grid.Row="2">
            <RepeatButton.Visibility>
             <MultiBinding FallbackValue="Visibility.Collapsed" Converter="{StaticResource MenuScrollingVisibilityConverter}" ConverterParameter="100">
              <Binding Path="ComputedVerticalScrollBarVisibility" RelativeSource="{RelativeSource TemplatedParent}"/>
              <Binding Path="VerticalOffset" RelativeSource="{RelativeSource TemplatedParent}"/>
              <Binding Path="ExtentHeight" RelativeSource="{RelativeSource TemplatedParent}"/>
              <Binding Path="ViewportHeight" RelativeSource="{RelativeSource TemplatedParent}"/>
             </MultiBinding>
            </RepeatButton.Visibility>
            <Path Fill="{DynamicResource {x:Static SystemColors.MenuTextBrushKey}}" Data="{StaticResource DownArrow}"/>
           </RepeatButton>
          </Grid>
         </ControlTemplate>
        </Setter.Value>
       </Setter>
      </Style>
      <ControlTemplate x:Key="{ComponentResourceKey ResourceId=TopLevelHeaderTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}" TargetType="{x:Type MenuItem}">
       <Border x:Name="Bd" SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
        <DockPanel>
         <ContentPresenter x:Name="Icon" Margin="4,0,6,0" VerticalAlignment="Center" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" ContentSource="Icon"/>
         <Path x:Name="GlyphPanel" Fill="{TemplateBinding Foreground}" FlowDirection="LeftToRight" Margin="4,0,6,0" VerticalAlignment="Center" Visibility="Collapsed" Data="{StaticResource Checkmark}"/>
         <ContentPresenter Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" ContentSource="Header" RecognizesAccessKey="True"/>
         <Popup x:Name="PART_Popup" AllowsTransparency="true" IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" Placement="Bottom" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}" Focusable="false">
          <Microsoft_Windows_Themes:SystemDropShadowChrome x:Name="Shdw" Color="Transparent">
           <Border x:Name="SubMenuBorder" Background="{DynamicResource {x:Static SystemColors.MenuBrushKey}}" BorderBrush="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" BorderThickness="1">
            <ScrollViewer CanContentScroll="true" MaxHeight="50">
            <!--ScrollViewer Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}" CanContentScroll="true"-->
             <ItemsPresenter Margin="2" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Grid.IsSharedSizeScope="true" KeyboardNavigation.DirectionalNavigation="Cycle" KeyboardNavigation.TabNavigation="Cycle"/>
            </ScrollViewer>
           </Border>
          </Microsoft_Windows_Themes:SystemDropShadowChrome>
         </Popup>
        </DockPanel>
       </Border>
       <ControlTemplate.Triggers>
        <Trigger Property="IsSuspendingPopupAnimation" Value="true">
         <Setter Property="PopupAnimation" TargetName="PART_Popup" Value="None"/>
        </Trigger>
        <Trigger Property="Icon" Value="{x:Null}">
         <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
        </Trigger>
        <Trigger Property="IsChecked" Value="true">
         <Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
         <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
        </Trigger>
        <Trigger Property="IsHighlighted" Value="true">
         <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
         <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
        </Trigger>
        <Trigger Property="IsEnabled" Value="false">
         <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
        </Trigger>
        <Trigger Property="HasDropShadow" SourceName="PART_Popup" Value="true">
         <Setter Property="Margin" TargetName="Shdw" Value="0,0,5,5"/>
         <Setter Property="Color" TargetName="Shdw" Value="#71000000"/>
        </Trigger>
       </ControlTemplate.Triggers>
      </ControlTemplate>
      <ControlTemplate x:Key="{ComponentResourceKey ResourceId=TopLevelItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}" TargetType="{x:Type MenuItem}">
       <Border x:Name="Bd" SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
        <DockPanel>
         <ContentPresenter x:Name="Icon" Margin="4,0,6,0" VerticalAlignment="Center" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" ContentSource="Icon"/>
         <Path x:Name="GlyphPanel" Fill="{TemplateBinding Foreground}" FlowDirection="LeftToRight" Margin="4,0,6,0" VerticalAlignment="Center" Visibility="Collapsed" Data="{StaticResource Checkmark}"/>
         <ContentPresenter Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" ContentSource="Header" RecognizesAccessKey="True"/>
        </DockPanel>
       </Border>
       <ControlTemplate.Triggers>
        <Trigger Property="Icon" Value="{x:Null}">
         <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
        </Trigger>
        <Trigger Property="IsChecked" Value="true">
         <Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
         <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
        </Trigger>
        <Trigger Property="IsHighlighted" Value="true">
         <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
         <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
        </Trigger>
        <Trigger Property="IsEnabled" Value="false">
         <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
        </Trigger>
       </ControlTemplate.Triggers>
      </ControlTemplate>
      <Geometry x:Key="RightArrow">M 0,0 L 4,3.5 L 0,7 Z</Geometry>
      <ControlTemplate x:Key="{ComponentResourceKey ResourceId=SubmenuHeaderTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}" TargetType="{x:Type MenuItem}">
       <Border x:Name="Bd" SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
        <Grid>
         <Grid.ColumnDefinitions>
          <ColumnDefinition SharedSizeGroup="MenuItemIconColumnGroup" MinWidth="17" Width="Auto"/>
          <ColumnDefinition Width="*"/>
          <ColumnDefinition SharedSizeGroup="MenuItemIGTColumnGroup" Width="Auto"/>
          <ColumnDefinition Width="14"/>
         </Grid.ColumnDefinitions>
         <ContentPresenter x:Name="Icon" Margin="4,0,6,0" VerticalAlignment="Center" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" ContentSource="Icon"/>
         <Path x:Name="GlyphPanel" Fill="{TemplateBinding Foreground}" FlowDirection="LeftToRight" Margin="4,0,6,0" VerticalAlignment="Center" Visibility="Hidden" Data="{StaticResource Checkmark}"/>
         <ContentPresenter Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Grid.Column="1" ContentSource="Header" RecognizesAccessKey="True"/>
         <Path Fill="{TemplateBinding Foreground}" Margin="4,0,6,0" VerticalAlignment="Center" Grid.Column="3" Data="{StaticResource RightArrow}" DockPanel.Dock="Right"/>
         <Popup x:Name="PART_Popup" AllowsTransparency="true" IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" Placement="Right" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}" VerticalOffset="-3" Focusable="false">
          <Microsoft_Windows_Themes:SystemDropShadowChrome x:Name="Shdw" Color="Transparent">
           <Border x:Name="SubMenuBorder" Background="{DynamicResource {x:Static SystemColors.MenuBrushKey}}" BorderBrush="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" BorderThickness="1">
            <ScrollViewer CanContentScroll="true" MaxHeight="50">
            <!--ScrollViewer Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}" CanContentScroll="true"-->
             <ItemsPresenter Margin="2" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Grid.IsSharedSizeScope="true" KeyboardNavigation.DirectionalNavigation="Cycle" KeyboardNavigation.TabNavigation="Cycle"/>
            </ScrollViewer>
           </Border>
          </Microsoft_Windows_Themes:SystemDropShadowChrome>
         </Popup>
        </Grid>
       </Border>
       <ControlTemplate.Triggers>
        <Trigger Property="IsSuspendingPopupAnimation" Value="true">
         <Setter Property="PopupAnimation" TargetName="PART_Popup" Value="None"/>
        </Trigger>
        <Trigger Property="Icon" Value="{x:Null}">
         <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
        </Trigger>
        <Trigger Property="IsChecked" Value="true">
         <Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
         <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
        </Trigger>
        <Trigger Property="HasDropShadow" SourceName="PART_Popup" Value="true">
         <Setter Property="Margin" TargetName="Shdw" Value="0,0,5,5"/>
         <Setter Property="Color" TargetName="Shdw" Value="#71000000"/>
        </Trigger>
        <Trigger Property="IsHighlighted" Value="true">
         <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
         <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
        </Trigger>
        <Trigger Property="IsEnabled" Value="false">
         <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
        </Trigger>
       </ControlTemplate.Triggers>
      </ControlTemplate>
      <Style x:Key="MenuItemStyle" TargetType="{x:Type MenuItem}">
       <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
       <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
       <Setter Property="Background" Value="Transparent"/>
       <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.MenuTextBrushKey}}"/>
       <Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=SubmenuItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
       <Style.Triggers>
        <Trigger Property="Role" Value="TopLevelHeader">
         <Setter Property="Margin" Value="0,1,0,1"/>
         <Setter Property="Padding" Value="6,3,6,3"/>
         <Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=TopLevelHeaderTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
        </Trigger>
        <Trigger Property="Role" Value="TopLevelItem">
         <Setter Property="Margin" Value="0,1,0,1"/>
         <Setter Property="Padding" Value="6,3,6,3"/>
         <Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=TopLevelItemTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
        </Trigger>
        <Trigger Property="Role" Value="SubmenuHeader">
         <Setter Property="DockPanel.Dock" Value="Top"/>
         <Setter Property="Padding" Value="0,2,0,2"/>
         <Setter Property="Template" Value="{DynamicResource {ComponentResourceKey ResourceId=SubmenuHeaderTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}}"/>
        </Trigger>
        <Trigger Property="Role" Value="SubmenuItem">
         <Setter Property="DockPanel.Dock" Value="Top"/>
         <Setter Property="Padding" Value="0,2,0,2"/>
        </Trigger>
       </Style.Triggers>
      </Style>
     </Window.Resources>

    • 回答としてマーク miyazawa 2010年10月21日 1:01
    2010年10月21日 1:00