Luke
Luke

Reputation: 6315

Default ContextMenu Style - WPF

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.

Upvotes: 13

Views: 28739

Answers (5)

Jonathan Perry
Jonathan Perry

Reputation: 3043

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>

Upvotes: 4

Jobi Joy
Jobi Joy

Reputation: 50028

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.

alt text

Upvotes: 1

dex3703
dex3703

Reputation: 2097

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. :)

Upvotes: 10

Luke
Luke

Reputation: 6315

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

Upvotes: 21

Robert Macnee
Robert Macnee

Reputation: 11820

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.

Upvotes: -1

Related Questions