Default ContextMenu Style - WPF

一个人想着一个人 提交于 2019-11-26 22:50:12

问题


I am trying to modify the default style of the ContextMenu in WPF.

Normally you can creat a copy of the default in Expression Blend using the Edit Control Parts (Template) > Edit a Copy menu option. However I can't work out how to do this with a ContextMenu. Any idea how I can get the default style to modify?

I am trying to disable the left side of the context menu where the icons are normally shown.

Thanks!

Update: Maybe I wasn't clear about removing the icons. For example, if you have a context menu with no icons then the whole left side of the menu is wasted space. I would like to modify the default style of the context menu background to remove this. Simply I don't know how to access this default style.


回答1:


For templates and styles that are not accessible through the Expression Interface (such as the ContextMenu template) you can use the following code to extract the template:

Dim sb As System.Text.StringBuilder = New System.Text.StringBuilder
Using Writer As TextWriter = New StringWriter(sb)
    System.Windows.Markup.XamlWriter.Save(ContextMenu.Template, Writer)
End Using
Debug.Write(sb.ToString)

Or in C#

var str = new StringBuilder();
using (var writer = new StringWriter(str))
    XamlWriter.Save(ContextMenu.Template, writer);
Debug.Write(str);



回答2:


I found the easy way to get the ContextMenu template in Blend:

  1. I added a ContextMenu to a button with some menuitems.
  2. Under "miscellaneous" in the properties pane, there's a grouped item for ContextMenu.
  3. Open this. You'll find the usual Style and Template properties.
  4. Click the square for the popup menu, and select Convert to New Resource...

That's it. Pick where you want the template/style to be put, and you're done.

Here's the markup I had:

<StackPanel x:Name="LayoutRoot">
    <Button Content="Click for ContextMenu" Width="30" HorizontalAlignment="Center" VerticalAlignment="Center">
        <Button.ContextMenu>
            <ContextMenu Template="{DynamicResource ContextMenuControlTemplate1}" Style="{DynamicResource ContextMenuStyle1}">
                <MenuItem Header="File"/>
                <MenuItem Header="Edit"/>
                <MenuItem Header="View"/>
                <MenuItem Header="Recent Files"/>
                    <MenuItem Header="file1.txt"/>
                    <MenuItem Header="file2.txt"/>
            </ContextMenu>
        </Button.ContextMenu>
    </Button>
</StackPanel>

And the style/template I got:

<Style x:Key="ContextMenuStyle1" TargetType="{x:Type ContextMenu}">
    <Setter Property="Background" Value="{DynamicResource MenuBackgroundBrush}"/>
    <Setter Property="BorderThickness" Value="1"/>
    <Setter Property="BorderBrush" Value="{DynamicResource WindowBorderBrush}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ContextMenu}">
                <Border Uid="Border_93">
                    <Border.Style>
                        <Style TargetType="{x:Type Border}">
                            <Setter Property="Tag" Value="{DynamicResource {x:Static SystemParameters.DropShadowKey}}"/>
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding Tag, RelativeSource={RelativeSource Self}}" Value="True">
                                    <Setter Property="Background" Value="Transparent"/>
                                    <Setter Property="Padding" Value="0,0,5,5"/>
                                    <Setter Property="Effect">
                                        <Setter.Value>
                                            <DropShadowEffect BlurRadius="4" Opacity="0.8" ShadowDepth="1"/>
                                        </Setter.Value>
                                    </Setter>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </Border.Style>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Hope this helps. In usual MS thoroughness, the brushes in the default style aren't found. :)




回答3:


Try this: (Put this code in your Resources part of your XAML) This should remove the icon strip from the context menu.

<Style TargetType="{x:Type ContextMenu}">
    <Setter Property="OverridesDefaultStyle" Value="True" />
    <Setter Property="SnapsToDevicePixels" Value="True" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ContextMenu}">
                <Border BorderThickness="1" CornerRadius="4" BorderBrush="Black" x:Name="Border" Background="White">
                    <StackPanel ClipToBounds="True" Orientation="Vertical" IsItemsHost="True" />
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="true">
                        <Setter TargetName="Border" Property="Background" Value="White" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>



回答4:


Actually the space is not part of the ContextMenu it is part of MenuItem. So just drag a MenuItem to your window in expression blend and create a copy of the control. Hope your ContextMenu declaration is as follows

 <ContextMenu  >
    <MenuItem Header="Copy"/>
    <MenuItem Header="Paste"/>
    <MenuItem Header="Clear"/>
 </ContextMenu>

And inside your MenuItem ControlTemplate you can see the space as bellow. So remove the Icon and First Column of the grid I marked in the screen shot.




回答5:


The extra space on the left is due to the little check mark that appears when you set IsCheckable and IsChecked to true on MenuItem.

The check mark is in the template for MenuItem so if you edit that you can take it out.



来源:https://stackoverflow.com/questions/641634/default-contextmenu-style-wpf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!