Pergunta

Eu estou trabalhando em alguns XAML em um aplicativo WPF e estou tendo alguns problemas começá-lo para fazer o que quero. Aqui está uma amostra do meu XAML:

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

Quando clico no botão de estouro da minha barra de ferramentas, os "Itens especiais" MenuItem aparece com uma pequena seta ao lado dele, indicando elementos aninhados. No entanto, quando eu passar o mouse sobre "Itens especiais" ou tentar clicar nele, os MenuItems "C" e "D" não estão sendo exibidos.

Eu estava esperando que MenuItem seria apenas fora do trabalho de um Menu, mas eu tentei fazer a coisa simples e direta, apenas no caso. Incluindo estes MenuItems dentro do menu e, em vez disso, dando a este menu a ToolBar.OverflowMode = propriedade "Always" produz alguns styling indesejada. A flecha não está mais presente, os "itens especiais" necessidades entrada de ser clicado para ativar o sub-menu e o posicionamento sub-menu parece um pouco fora.

Alguém sabe o que está acontecendo?

Edit: Adicionando um menu para o transbordamento está produzindo exatamente o que eu pedi (grande surpresa). O que eu sou depois é uma maneira de converter cabeçalhos e itens de nível superior para o nível sub-menu. Eu virei para este exemplo modelo de controle sobre MSDN para uma solução de (abaixo).

Editar, Editar: @gcores (comentário de discussão): Sério? Estou faltando alguma coisa?

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

Este trecho não funciona para mim. I tem que clicar em 'Especial' para o sub-menu para exibição.

Foi útil?

Solução

A única maneira que eu poderia encontrar para sequer chegar perto de gerar este comportamento era criar um menu no estouro que continha um item de menu único cujo cabeçalho era em si um outro item de menu chamado "Itens especiais" e com os filhos adequadas. Ele trabalhou como pretendido, mas parecia bizarra (que pode ser sanado por modelos personalizados) e também parece ser uma enorme hack. A única maneira "correta" de fazer isso que eu posso pensar seria fazer o seu próprio MenuItem-like de controle que aparece um ContextMenu ou Popup quando pairado sobre, desde que eu não acho que um ControlTemplate personalizado pode alterar o comportamento padrão de um menu de modo a não exigir um clique no item de nível superior.

Outras dicas

Outra solução é usar os modelos existentes e substituir o modelo para o TopLevelHeader com o modelo do 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>

E usar este estilo em seu nível superior MenuItem. Isso deve simplificar o seu código.

Editar : Você está certo, ele só funciona quando você clicar nele (não sei como eu me convenci de que funcionou, desculpe :)). É de funcionalidade é como um TopLevelMenu embora o modelo diz o contrário, é bem confuso.

A única coisa que posso pensar é a adição de um gatilho para mostrar o submenu em IsMenuOver e manipular o evento Click para que ele não faz nada, mas eu não sei o quão bem que iria trabalhar.

Depois de mais leitura, uma solução que estou usando é abaixo.

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

Eu atacar o comportamento de 'SubmenuPopup' em um mouse-over, em vez de manipular o evento clique. Eu gostaria de entender isso mais plenamente, então eu tentei comentar esta parte do gatilho e adicionando um manipulador de eventos que chama um método 'DoNothing ()' no evento 'PreviewMouseDown'. Acontece que eu estou faltando alguma coisa e eu acho que ela está relacionada com a focagem e / ou como um menu lida com a sua coleção de itens. Não permitindo que um evento para propagar após 'DoNothing ()' (routedEventArgs.Handled = true) parece eliminar os problemas ao clicar no item de menu "Itens especiais". No entanto, se um navegado fora do menu ou adicionado outro item de menu e, em seguida, clicar em que, o comportamento de foco pode ser desligado ou ligado e desligado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top