簡體   English   中英

在使用用戶定義模板的菜單項中插入圖標

[英]Insert an icon in menu item that uses an user defined Template

我想要一個帶有菜單項自定義背景顏色的下拉菜單。 我能夠在這個答案的幫助下實現這一目標。 我的 GUI 中的根菜單項只有一個沒有Header的圖標。 我用來定義菜單項圖標的代碼如下:

<Style x:Key="MenuIcon" TargetType="{x:Type MenuItem}">
    <Setter Property="SnapsToDevicePixels" Value="True" />
    <Setter Property="OverridesDefaultStyle" Value="True" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type MenuItem}">
                 <Menu Background="Orange">
                     <MenuItem ToolTip="Menu" BorderBrush="White">
                          <MenuItem.Header>
                               <StackPanel
                                   Width="60"
                                   Height="50"
                                   HorizontalAlignment="Center"
                                   VerticalAlignment="Center"
                                   Background="Orange"
                                   Orientation="Horizontal">
                                   <Viewbox
                                       Margin="9"
                                       HorizontalAlignment="Center"
                                       VerticalAlignment="Center"
                                       Stretch="Fill">
                                       <Grid Margin="-8,0,0,0">
                                          <Path
                                              x:Name="MenuIconFillStyle"
                                              HorizontalAlignment="Center"
                                              VerticalAlignment="Center"
                                              Data="M6 36v-3h36v3Zm0-10.5v-3h36v3ZM615v-3h36v3Z"
                                              Fill="White" />
                                       </Grid>
                                   </Viewbox>
                               </StackPanel>
                           </MenuItem.Header>
                        </MenuItem>
                     </Menu>

                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                             <Setter TargetName="MenuIconFillStyle" Property="Fill" Value="Yellow" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

我在取自此處<ControlTemplate x:Key="MenuItemControlTemplate1" TargetType="{x:Type MenuItem}">中添加了以下內容:

 <ContentPresenter x:Name="Icon" Content="{TemplateBinding Icon}" ContentSource="Icon" HorizontalAlignment="Center" Height="16" Margin="3" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Width="16"/>

以及ControlTemplate.Triggers中的以下內容:

<Trigger Property="Icon" Value="True">
     <Setter Property="Visibility" TargetName="Icon" Value="Visible"/>
</Trigger>

Template="{DynamicResource MenuItemControlTemplate1}"如下:

<ControlTemplate x:Key="MenuItemControlTemplate1" TargetType="{x:Type MenuItem}">
            <Border x:Name="templateRoot" 
                    BorderBrush="#535353" 
                    CornerRadius="3" 
                    BorderThickness="1" 
                    Background="{TemplateBinding Background}" 
                    SnapsToDevicePixels="True">
                <Grid VerticalAlignment="Center">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto"/>
                        <ColumnDefinition Width="Auto"/>
                    </Grid.ColumnDefinitions>

                    <ContentPresenter x:Name="Icon" Content="{TemplateBinding Icon}" ContentSource="Icon" HorizontalAlignment="Center" Width="26" Height="16" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" />
                    <ContentPresenter ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.Column="1" ContentStringFormat="{TemplateBinding HeaderStringFormat}" ContentSource="Header" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    <Popup x:Name="PART_Popup"  AllowsTransparency="True" Focusable="False" IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}" Placement="Bottom" HorizontalOffset="-2">
                        <Border x:Name="SubMenuBorder" BorderBrush="#595959" BorderThickness="1" Background="#3A3A3A" Padding="2">
                            <ScrollViewer x:Name="SubMenuScrollViewer" Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}">
                                <Grid RenderOptions.ClearTypeHint="Enabled">
                                    <Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
                                        <Rectangle x:Name="OpaqueRect" Fill="{Binding Background, ElementName=SubMenuBorder}" Height="{Binding ActualHeight, ElementName=SubMenuBorder}" Width="{Binding ActualWidth, ElementName=SubMenuBorder}"/>
                                    </Canvas>
                                    <ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Cycle" Grid.IsSharedSizeScope="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.TabNavigation="Cycle"/>
                                </Grid>
                            </ScrollViewer>
                        </Border>
                    </Popup>
                </Grid>
            </Border>
            <ControlTemplate.Triggers>
                <Trigger Property="Icon" Value="True">
                    <Setter Property="Visibility" TargetName="Icon" Value="Visible"/>
                </Trigger>
                <Trigger Property="IsSuspendingPopupAnimation" Value="True">
                    <Setter Property="PopupAnimation" TargetName="PART_Popup" Value="None"/>
                </Trigger>
                <Trigger Property="IsHighlighted" Value="True">
                    <Setter Property="Background" TargetName="templateRoot" Value="{StaticResource DarkBrush}"/>
                    <Setter Property="BorderBrush" TargetName="templateRoot" Value="#2C2C2C"/>
                    <Setter Property="BorderThickness" TargetName="templateRoot" Value="1"></Setter>
                </Trigger>

                <Trigger Property="CanContentScroll" SourceName="SubMenuScrollViewer" Value="False">
                    <Setter Property="Canvas.Top" TargetName="OpaqueRect" Value="{Binding VerticalOffset, ElementName=SubMenuScrollViewer}"/>
                    <Setter Property="Canvas.Left" TargetName="OpaqueRect" Value="{Binding HorizontalOffset, ElementName=SubMenuScrollViewer}"/>
                </Trigger>
                <Trigger Property="IsKeyboardFocusWithin" Value="True">
                    <Setter TargetName="templateRoot" Property="Background" Value="{StaticResource Clicked}" />
                    <Setter Property="Header" Value="Test" />
                    <Setter Property="BorderBrush" Value="#2C2C2C"></Setter>
                    <Setter Property="BorderThickness" Value="1"></Setter>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>

MenuItem的自定義背景和圖標在以下代碼片段中指定:

<Grid Background="#535353">
    <Menu Width="100" Height="22" Margin="10, 10, 5, 5" HorizontalAlignment="Left" Background="White" VerticalAlignment="Top">
        <MenuItem Style="{StaticResource MenuIcon}" Template="{DynamicResource MenuItemControlTemplate1}">
    </Menu>
</Grid>

Style中定義的圖標不會與用於設置背景顏色的模板 ( Template="{DynamicResource MenuItemControlTemplate1}" ) 一起呈現在MenuItem中。 如何實現?

編輯

根據@mm8的建議,我嘗試結合負責更改背景顏色的Styles(從這里借用的帶有x:Key="TopLevelHeaderStyle"的樣式)並在根菜單中插入菜單項圖標和想出了以下內容:

 <Style x:Key="TopLevelHeaderStyle" TargetType="{x:Type MenuItem}">
            <Setter Property="Background" Value="#000d18"/>
            <Setter Property="Foreground" Value="#d8d8d8"/>
            <Setter Property="Width" Value="72"/>
            <Setter Property="Height" Value="42"/>
            <Setter Property="FontSize" Value="16"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type MenuItem}">
                        <Border x:Name="MenuItemBorder" Width="72" Height="42" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
                            <Grid VerticalAlignment="Center">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto"/>
                                    <ColumnDefinition Width="Auto"/>
                                </Grid.ColumnDefinitions>
                                <ContentPresenter Content="{TemplateBinding Header}" ContentSource="Header" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                                <Popup AllowsTransparency="True" IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" Placement="Bottom" PlacementTarget="{Binding ElementName=MenuItemBorder}"
                                   HorizontalOffset="1" VerticalOffset="-1">
                                    <Border BorderBrush="#414141" Background="#414141">
                                        <ScrollViewer Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}">
                                            <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                                        </ScrollViewer>
                                    </Border>
                                </Popup>
                            </Grid>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsHighlighted" Value="True">
                                <Setter Property="Background" Value="#1271C8"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <!--MenuIcon-->
        <Style x:Key="MenuIcon" TargetType="{x:Type MenuItem}" BasedOn="{StaticResource TopLevelHeaderStyle}">
            <Setter Property="SnapsToDevicePixels" Value="True" />
            <Setter Property="OverridesDefaultStyle" Value="True" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type MenuItem}">
                        <Menu>
                            <MenuItem>
                                <MenuItem.Header>
                                    <StackPanel
                            Width="60"
                            Height="50"
                            HorizontalAlignment="Center"
                            VerticalAlignment="Center"
                            Background="Orange"
                            Orientation="Horizontal">
                                        <Viewbox
                                Margin="9"
                                HorizontalAlignment="Center"
                                VerticalAlignment="Center"
                                Stretch="Fill">
                                            <Grid Margin="-8,0,0,0">
                                                <Path x:Name="MenuIconFillStyle"
                                        HorizontalAlignment="Center"
                                        VerticalAlignment="Center"
                                        Fill="White"              
                                        Data="M6 36v-3h36v3Zm0-10.5v-3h36v3ZM6 15v-3h36v3Z"
                                       />
                                            </Grid>
                                        </Viewbox>
                                    </StackPanel>
                                </MenuItem.Header>
                            </MenuItem>
                        </Menu>

並按如下方式使用它:

<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="50" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="auto" />
            <ColumnDefinition Width="auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>


        <Menu Grid.Column="0" FontSize="24" HorizontalAlignment="Left" VerticalAlignment="Top">
            <MenuItem  Header="File" Style="{StaticResource TopLevelHeaderStyle}">
                <MenuItem Header="New"/>
                <MenuItem Header="Open"/>
                <MenuItem Header="Close"/>
            </MenuItem>
        </Menu>

        <Menu Grid.Column="1"  FontSize="24" HorizontalAlignment="Left" VerticalAlignment="Top">
            <MenuItem Margin="-11, 0,0,0" Width="50" Header="File" Style="{StaticResource MenuIcon}">
                <MenuItem Header="New1"/>
                <MenuItem Header="Open1"/>
                <MenuItem Header="Close1"/>
            </MenuItem>
        </Menu>
    </Grid>

現在在根菜單項中有一個圖標的下拉菜單沒有顯示其他菜單項內容New1Open1Close1我犯了什么錯誤?

MenuItem 控件有一個名為“Icon”的類型為 Object 的 DependencyProperty。 此屬性僅供您使用。

首先,您需要將 MenuItem ControlTemplate 中 Path 中的數據綁定到父 MenuItem 的 Icon 屬性。 像這樣:

<Path x:Name="MenuIconFillStyle"
   HorizontalAlignment="Center"
   VerticalAlignment="Center"
   Data="{TemplateBinding Icon}"
   Fill="White" />

現在您可以像這樣在 XAML 中指定一個 PathGeometry。 其內容將是您的 SVG 數據:

<PathGeometry x:Key="MySpecialPath">M2 0C0.89687</PathGeometry>

最后,使用其 Key 將此路徑作為 StaticResource 應用於任何 MenuItem:

<Menu Width="100" Height="22" Margin="10, 10, 5, 5" HorizontalAlignment="Left" Background="White" VerticalAlignment="Top">
    <MenuItem Template="{DynamicResource MenuItemControlTemplate1}"
              Icon="{StaticResource MySpecialPath}">
</Menu>

如果你想更多地控制你的圖標(多個 colors,不同的大小,邊距等),它會涉及更多。 請記住,MenuItem 上的“Path”屬性是 Object,因此您可以假設在 MenuItem ControlTemplate 和 TemplateBind 中使用任何“Presenting”元素(不需要是 Path),將其綁定到 MenuItem.Path - 然后傳遞任何類型的“Presented” ' object 到 MenuItem(不需要是 PathGeometry)。 您可以考慮使用

<ContentPresenter Content="{TemplateBinding Icon}" />

而不是 MenuItem ControlTemplate 中的 Path 控件 - 然后將任何“圖標”控件賦予 XAML 中的 MenuItem.Path 屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM