2009-04-10 28 views
9

wpfアプリケーション用のXAMLで作業しています。ここに私のXAMLのサンプルです:WPF:ToolBar内のネストされたMenuItem

<!-- Tool Bar Tray --> 
<ToolBarTray Name="toolBarTray1" DockPanel.Dock="Top"> 
    <!-- File And Edit Tools --> 
    <ToolBar Name="toolBar1" Band="1" BandIndex="1"> 
     <!-- Regular Items --> 
     <Button>A</Button> 
     <Button>B</Button> 
     <!-- Overflow Menu For Special Items --> 
     <MenuItem ToolBar.OverflowMode="Always" Header="Special Items"> 
      <MenuItem Header="C"/> 
      <MenuItem Header="D"/> 
     </MenuItem> 
    </ToolBar> 
</ToolBarTray> 

私は私のツールバーのオーバーフローボタンをクリックすると、「特別項目」のMenuItemは、ネストされた要素を示し、その横に小さな矢印が表示されます。しかし、「特別なアイテム」の上にマウスを置いたり、それをクリックしようとすると、MenuItemsの「C」と「D」は表示されません。

私はMenuItemがメニューの外で動作することを望んでいましたが、私はまっすぐなことをやってみました。これらのMenuItemをメニュー内に含め、代わりに、このメニューにToolBar.OverflowMode = "Always"プロパティを指定すると、不要なスタイルが生成されます。矢印はもはや存在せず、サブメニューをアクティブにするためには「特別なアイテム」の項目をクリックする必要があり、サブメニューの配置は少し見える。

何が起こっているのか分かりませんか?

編集:オーバーフローにメニューを追加すると、私が要求したものを正確に生成できます(大きな驚き)。私が後にしているのは、トップレベルのヘッダーとアイテムをサブメニューレベルに変換する方法です。私は解決策(下記)のMSDNのこのコントロールテンプレートの例に向けました。

編集: @gcores(コメント欄):本当ですか?何か不足していますか?

<ToolBar Name="toolBar1" Band="1" BandIndex="4"> 
    <!-- Displayed Buttons --> 
    <Button>A</Button> 
    <Button>B</Button> 
    <!-- Special Items Menu --> 
    <Menu ToolBar.OverflowMode="Always" > 
     <MenuItem Style="{StaticResource MenuItemStyle}" Header="Special"> 
      <MenuItem Header="C"/> 
      <MenuItem Header="D"/> 
     </MenuItem> 
    </Menu> 
</ToolBar> 

このスニペットは私にとっては機能しません。サブメニューを表示するには「特別」をクリックする必要があります。

答えて

0

この動作を生成することに近づくことさえできる唯一の方法は、ヘッダー自体が「特別なアイテム」という別のメニューアイテムで、適切な子を含む単一のメニューアイテムを含むオーバーフローでメニューを作成することでした。これは意図したとおりに動作しましたが、奇妙に見えます(これはカスタムテンプレートによって修正される可能性があります)。また、巨大なハックのように見えます。これを行うための唯一の「適切な」方法は、カスタムのControlTemplateがデフォルトの動作を変更できるとは考えていないので、ContextMenuまたはPopupをポップアップする独自のMenuItemのようなコントロールを作成することですトップレベルの項目をクリックしないようにするメニュー。

1

もっと読んだら、私が使っている解決策は以下の通りです。

<!-- Resource Dictionary Stuff --> 

<!-- Some Brushes --> 
<SolidColorBrush x:Key="Brush_1" 
    Color="White" /> 

<LinearGradientBrush x:Key="Brush_2" 
    StartPoint="0 0" 
    EndPoint="0 1"> 

    <GradientStop 
     Color="White" 
     Offset="0"/> 

    <GradientStop 
     Color="DarkSeaGreen" 
     Offset="1"/> 

</LinearGradientBrush> 

<SolidColorBrush x:Key="Brush_3" 
    Color="DarkOliveGreen"/> 

<!-- Custom MenuItem - Top Level Header - Style 1 --> 
<Style x:Key="MenuItem_TLH_Style1" 
    TargetType="MenuItem"> 

    <!--<EventSetter Event="PreviewMouseDown" Handler="DoNothing"/>--> 

    <Setter Property="Template"> 
     <Setter.Value> 

      <ControlTemplate x:Name="ControlTemplate" 
       TargetType="MenuItem"> 

       <!-- A headered text that may display a submenu 
        on a trigger. This submenu is the host for a 
        menu item's items. --> 
       <Border x:Name="BoundaryBorder" 
        Background="{StaticResource Brush_1}" 
        BorderThickness="1"> 

        <Grid x:Name="ContainerGrid"> 

         <ContentPresenter x:Name="HeaderContent" 
          Margin="6 3 6 3" 
          ContentSource="Header" 
          RecognizesAccessKey="True"/> 

         <Popup x:Name="SubmenuPopup" 
          Placement="Bottom" 
          IsOpen="{TemplateBinding IsSubmenuOpen}" 
          AllowsTransparency="True" 
          Focusable="False" 
          PopupAnimation="Fade"> 

          <Border x:Name="SubmenuBoundaryBorder" 
           SnapsToDevicePixels="True" 
           Background="{StaticResource Brush_1}" 
           BorderBrush="{StaticResource SolidBorderBrush}" 
           BorderThickness="1"> 

           <StackPanel x:Name="ItemsStackPanel" 
            IsItemsHost="True" 
            KeyboardNavigation.DirectionalNavigation="Cycle"/> 

          </Border> 
         </Popup> 
        </Grid> 
       </Border> 

       <ControlTemplate.Triggers> 

        <!-- --> 
        <Trigger 
         Property="IsSuspendingPopupAnimation" 
         Value="true"> 

         <Setter 
          TargetName="SubmenuPopup" 
          Property="PopupAnimation" 
          Value="Fade"/> 

        </Trigger> 

        <!-- On mouse-over, show the submenu and highlight the header. --> 
        <Trigger 
         Property="IsMouseOver" 
         Value="true"> 

         <Setter 
          TargetName="BoundaryBorder" 
          Property="Background" 
          Value="{StaticResource Brush_2}"/> 

         <Setter 
          TargetName="BoundaryBorder" 
          Property="BorderBrush" 
          Value="{StaticResource Brush_3}"/> 

         <Setter 
          Property="IsSubmenuOpen" 
          Value="true"/> 

         <!-- sloppy? --> 
         <Setter 
          TargetName="SubmenuPopup" 
          Property="IsOpen" 
          Value="true"/> 

        </Trigger> 

        <Trigger 
         SourceName="SubmenuPopup" 
         Property="AllowsTransparency" 
         Value="true"> 

         <Setter 
          TargetName="SubmenuBoundaryBorder" 
          Property="CornerRadius" 
          Value="0 0 4 4"/> 

         <Setter 
          TargetName="SubmenuBoundaryBorder" 
          Property="Padding" 
          Value="0 0 0 3"/> 

        </Trigger> 

        <!-- Visually indicate an unaccessible menu item. --> 
        <Trigger 
         Property="IsEnabled" 
         Value="false"> 

         <Setter 
          Property="Foreground" 
          Value="{StaticResource DisabledForegroundBrush}"/> 

        </Trigger> 
       </ControlTemplate.Triggers> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

<!-- ... --> 

<!-- Inside a window XAML file --> 

<!-- Tool Bar Tray --> 
<ToolBarTray x:Name="toolBarTray1" 
    DockPanel.Dock="Top"> 

    <!-- File And Edit Tools --> 
    <ToolBar x:Name="toolBar1" 
     Band="1" BandIndex="1"> 

     <!-- Displayed Buttons --> 
     <Button x:Name="ButtonA" 
      Content="A"/> 

     <Button x:Name="ButtonB" 
      Content="B"/> 

     <!-- Overflow Menu For Special Items --> 
     <Menu x:Name="OverflowMenu" 
      ToolBar.OverflowMode="Always"> 

      <MenuItem x:Name="SpecialsMenuItem" 
       Style="{StaticResource MyStyle}" 
       Header="Special Items"> 

       <MenuItem x:Name="CMenuItem" 
        Header="C"> 

        <MenuItem x:Name="DMenuItem" 
         Header="D"/> 

       </MenuItem> 
      </MenuItem> 
     </Menu> 
    </ToolBar> 
</ToolBarTray> 

クリックイベントを処理するのではなく、マウスオーバーで「SubmenuPopup」の動作を攻撃します。私はこれをより完全に理解したいので、トリガのこの部分をコメントアウトし、 'PreviewMouseDown'イベントで 'DoNothing()'メソッドを呼び出すイベントハンドラを追加しました。私は何かが欠けていることが判明し、それはフォーカスに関連していると思っています。 'DoNothing()'(routedEventArgs.Handled = true)の後にイベントが伝播するのを許可しないと、 "Special Items"メニュー項目をクリックしたときの問題が解消されているようです。ただし、メニューから移動したり、別のメニュー項目を追加してクリックしたりすると、ホバーの動作をオフにするか、オン/オフを切り替えることができます。

2

もう1つの解決方法は、既存のテンプレートを使用して、TopLevelHeaderのテンプレートをSubmenuHeaderのテンプレートで上書きすることです。

<Style x:Key="MenuItemStyle" TargetType="{x:Type MenuItem}"> 
    <Style.Triggers> 
    <Trigger Property="Role" Value="TopLevelHeader"> 
     <Setter Property="Template" 
       Value="{StaticResource {x:Static MenuItem.SubmenuHeaderTemplateKey}}"/> 
    </Trigger> 
    </Style.Triggers> 
</Style> 

トップスタイルのMenuItemでこのスタイルを使用します。それはあなたのコードを簡素化するはずです。

EDIT: あなたは正しい、あなたがそれをクリックすると、それだけで動作します(私はそれが働いていた自分自身を確信させたのか分からない、申し訳ありません:))。 テンプレートがそうでないと言っても、その機能はTopLevelMenuに似ています。

私が考えることができるのは、IsMenuOverにサブメニューを表示するトリガーを追加し、Clickイベントを処理するだけで何もしませんが、それがうまくいくかどうかわかりません。

+0

あなたが知っている、これは私が最初にやろうとしていたものです。私はMSDNを熟読し、Roleプロパティを見つけましたが、それを変更する正しい方法がわかりませんでした。私はそれから、私が上に掲載したクイックフィックスカットアンドペーストの怪物を見つけました。私はwpfに新しいです。 私はコードを試しましたが、残念ながら、サブメニューがマウスオーバーに表示されていません。私はもう少しそれを調べます。 –

+0

ああ、MenuItemをメニューにラップします。それ以外の場合、機能はありません。私はそれを試して、それは動作します。 – gcores

+0

OPの「編集、編集」を参照してください。 –

関連する問題