9

私は wpf アプリケーション用の XAML に取り組んでいますが、やりたいことを実行するのに問題があります。これが私の 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>

ツールバーのオーバーフロー ボタンをクリックすると、"Special Items" MenuItem が表示され、その横に小さな矢印が表示され、ネストされた要素を示します。しかし、「スペシャルアイテム」の上にマウスを置くかクリックしようとすると、MenuItems「C」と「D」が表示されません。

MenuItem が Menu の外部で機能することを望んでいましたが、念のため、簡単なことをしようとしました。これらの MenuItems を Menu 内に含め、代わりにこの Menu に 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>

このスニペットは私にはうまくいきません。サブメニューを表示するには、[スペシャル] をクリックする必要があります。

4

3 に答える 3

2

もう 1 つの解決策は、既存のテンプレートを使用し、TopLevelHeader の Template を SubmenuHeader の Template でオーバーライドすることです。

<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 で使用します。これにより、コードが簡素化されます。

編集:そうです、クリックしたときにのみ機能します(どのように機能すると確信したかわかりません、申し訳ありません:))。その機能は TopLevelMenu のようなものですが、テンプレートはそうではないと言っていますが、非常に紛らわしいです。

私が考えることができる唯一のことは、IsMenuOver にサブメニューを表示するトリガーを追加し、Click イベントを処理することです。

于 2009-04-15T22:39:15.533 に答える
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) の後にイベントが伝播されないようにすることで、[特別なアイテム] メニュー項目をクリックしたときの問題が解消されるようです。ただし、メニューから移動するか、別のメニュー項目を追加してからクリックすると、ホバー動作をオフにするか、オンとオフを切り替えることができます。

于 2009-04-12T04:15:32.967 に答える
0

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

于 2009-04-12T01:48:21.087 に答える