2009-04-10 3 views
9

에 나는 WPF 응용 프로그램에 대한 몇 가지 XAML에서 일하고 내가 원하는 것을 할을 받고 몇 가지 문제가 발생하고있다.WPF : 중첩 된 메뉴 아이템은 툴바

<!-- 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의 중첩 된 요소를 나타내는, 옆에 작은 화살표가 나타납니다 : 여기 내 XAML의 샘플입니다. 그러나 "Special Items"위에 마우스를 올리거나 클릭하려고하면 MenuItems "C"와 "D"가 표시되지 않습니다.

것은 내가 MenuItem을 그냥 메뉴의 외부에서 작동 것이라고 기대했다,하지만 난 단지의 경우, 직선 앞으로 일을하려고 노력했다. 이러한 MenuItem을 메뉴 안에 포함하고 대신이 메뉴에 ToolBar.OverflowMode = "Always"속성을 지정하면 원치 않는 스타일이 생성됩니다. 화살표는 더 이상 존재하지 않으며 하위 메뉴를 활성화하려면 "Special Items"항목을 클릭해야하며 하위 메뉴 위치는 약간 벗어납니다.

무슨 일이 일어나는지 아는 사람이 있습니까?

편집 : 추가 오버플로 메뉴가 나는 (깜짝 놀랄) 요청 정확히 무엇을 생산하고있다. 내가하는 일은 최상위 레벨의 헤더와 항목을 하위 메뉴 수준으로 변환하는 방법입니다. 나는 해결책 (아래)을 위해 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> 

나는 Click 이벤트를 처리하는 대신 마우스 오버시 'SubmenuPopup'의 동작을 공격합니다. 이 부분을 완전히 이해하고 싶습니다. 그래서 트리거의이 부분을 주석 처리하고 'PreviewMouseDown'이벤트에서 'DoNothing()'메서드를 호출하는 이벤트 처리기를 추가했습니다. 내가 뭔가를 놓치고있는 것으로 밝혀졌고 초점 맞추기 및/또는 메뉴가 항목 컬렉션을 처리하는 방법과 관련 있다고 생각됩니다. 'DoNothing()'(routedEventArgs.Handled = true) 이후에 이벤트를 전파하지 못하게하면 "Special Items"메뉴 항목을 클릭 할 때 발생하는 문제를 해결할 수 있습니다. 그러나 메뉴에서 다른 메뉴 항목을 탐색하거나 다른 메뉴 항목을 추가 한 다음 해당 항목을 클릭하면 호버 동작을 끄거나 켜고 끌 수 있습니다.

2

또 다른 방법은 기존 템플릿을 사용하고 SubmenuHeader의 템플릿과 TopLevelHeader의 템플릿을 무시하는 것입니다.

<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> 

최상위 메뉴 항목에서이 스타일을 사용하십시오. 그건 당신의 코드를 단순화해야합니다.

편집 : 당신은 당신이 그것을 클릭 할 때 만 작동 맞아 (:), 내가이 일을 자신을 설득하는 방법 미안 모른다). 템플릿은 달리 말하면서도 기능이 TopLevelMenu와 비슷하지만 매우 혼란 스럽습니다.

내가 생각할 수있는 것은 IsMenuOver에 하위 메뉴를 표시하고 Click 이벤트를 처리하기 위해 트리거를 추가하는 것 뿐이므로 아무 것도하지 않지만 작동하는 방법을 잘 모릅니다.

+0

알다시피, 이것은 제가 처음에 시도한 것입니다. MSDN을 정독하고 Role 속성을 찾았지만 올바르게 변경하는 방법을 알지 못했습니다. 나는 그때 위에 올려 놓은 quick-fix cut and paste 괴물을 발견했다. 나는 wpf에 처음이다. 코드를 시도했지만 불행히도 마우스 오버시 하위 메뉴가 표시되지 않습니다. 좀 더 조사하겠습니다. –

+0

오 MenuItem을 메뉴에 랩핑하십시오. 그렇지 않으면 기능이 없습니다. 나는 그것을 시도하고 그것을 작동합니다. – gcores

+0

OP의 "편집, 편집"을 참조하십시오. –