Question

I have a ContextMenu defined in XAML as follows:

<ContextMenu x:Name="deleteContextMenu">
    <ContextMenu.BitmapEffect>
        <DropShadowBitmapEffect Color="#FFB3C7E5" Direction="-60" ShadowDepth="5" Opacity="0.8"/>
    </ContextMenu.BitmapEffect>

    <MenuItem Header="Delete" Click="DeleteMenuItem_Click" Name="DeleteMenuItem" Background="{StaticResource ContextMenuBrush}">
        <MenuItem Header="DeleteChild" Name="DeleteMenuItem2" Background="{StaticResource ContextMenuBrush}">
        </MenuItem>
    </MenuItem>
</ContextMenu>

My custom DropShadow is applied to the main ContextMenu pop-up, but when I click the MenuItem, the submenu pop-up still has the horrible default shadow that looks terribly out of place with my color scheme. How can I force all submenus to have the same custom DropShadow effect?

UPDATE:

if I hack the visual tree for a MenuItem on the main context menu pop-up thusly:

StackPanel menuStackPanel = VisualTreeHelper.GetParent(menuItem as DependencyObject) as StackPanel;
Border border = VisualTreeHelper.GetParent(menuStackPanel) as Border;
border.Background = Brushes.Red;

I can control the color of the main pop-up.

For a subMenuItem in the submenu pop-up, there is no parent of any type returned by the visual tree helper.

Was it helpful?

Solution

I have a hacky suggestion:

    <ContextMenu x:Name="deleteContextMenu">
        <ContextMenu.BitmapEffect>
            <DropShadowBitmapEffect Color="#FFB3C7E5" Direction="-60" ShadowDepth="5" Opacity="0.8"/>
        </ContextMenu.BitmapEffect>
        <ContextMenu.Resources>
            <Style TargetType="{x:Type PopupRoot}">
                <Setter Property="BitmapEffect">
                    <Setter.Value>
                        <DropShadowBitmapEffect Color="#FFB3C7E5" Direction="-60" ShadowDepth="5" Opacity="0.8"/>
                    </Setter.Value>
                </Setter>
            </Style>
        </ContextMenu.Resources>

        <MenuItem Header="Delete" Name="DeleteMenuItem" Background="White" UsesItemContainerTemplate="True">
            <MenuItem Header="DeleteChild" Name="DeleteMenuItem2" Background="White" UsesItemContainerTemplate="True">
            </MenuItem>
        </MenuItem>
    </ContextMenu>

The child items of a MenuItem are displayed in a Popup (can be seen in MenuItem ControlTemplate Example. Thanks to this and snoop the style <Style TargetType="{x:Type PopupRoot}"> should apply the shadow to the child items.

Plan B:

You'll need to add the PresentationFramework.Classic (or another Aero etc.) assembly to the project.

xmlns:mwt="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Classic

    <ControlTemplate TargetType="MenuItem" x:Key="miTest">
        <Grid SnapsToDevicePixels="True">
            <Rectangle RadiusX="2" RadiusY="2" Fill="{TemplateBinding Panel.Background}" Stroke="{TemplateBinding Border.BorderBrush}" StrokeThickness="1" Name="Bg" />
            <Rectangle RadiusX="2" RadiusY="2" Stroke="#00FFFFFF" StrokeThickness="1" Name="InnerBorder" Margin="1,1,1,1" />
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" MinWidth="24" SharedSizeGroup="MenuItemIconColumnGroup" />
                    <ColumnDefinition Width="4" />
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="37" />
                    <ColumnDefinition Width="Auto" SharedSizeGroup="MenuItemIGTColumnGroup" />
                    <ColumnDefinition Width="17" />
                </Grid.ColumnDefinitions>
                <ContentPresenter Content="{TemplateBinding MenuItem.Icon}" ContentSource="Icon" Name="Icon" Margin="1,1,1,1" VerticalAlignment="Center" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
                <Border BorderThickness="1,1,1,1" CornerRadius="3,3,3,3" BorderBrush="#FFCDD3E6" Background="#FFE6EFF4" Name="GlyphPanel" Width="22" Height="22" Margin="1,1,1,1" Visibility="Hidden">
                    <Path Data="M0,5.1L1.7,5.2 3.4,7.1 8,0.4 9.2,0 3.3,10.8z" Fill="#FF0C12A1" Name="Glyph" Width="9" Height="11" FlowDirection="LeftToRight" />
                </Border>
                <ContentPresenter RecognizesAccessKey="True" Content="{TemplateBinding HeaderedContentControl.Header}" ContentTemplate="{TemplateBinding HeaderedContentControl.HeaderTemplate}" ContentStringFormat="{TemplateBinding HeaderedItemsControl.HeaderStringFormat}" ContentSource="Header" Margin="{TemplateBinding Control.Padding}" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" Grid.Column="2" />
                <TextBlock Text="{TemplateBinding MenuItem.InputGestureText}" Margin="{TemplateBinding Control.Padding}" Visibility="Collapsed" Grid.Column="4" />
                <Path Data="M0,0L4,3.5 0,7z" Fill="{TemplateBinding TextElement.Foreground}" Margin="4,0,0,0" VerticalAlignment="Center" Grid.Column="5" />
            </Grid>
            <Popup IsOpen="{TemplateBinding IsSubmenuOpen}" Placement="Right" HorizontalOffset="-2" VerticalOffset="-3" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}" AllowsTransparency="True" Name="PART_Popup" Focusable="False">
                <mwt:SystemDropShadowChrome Color="#00FFFFFF" Name="Shdw">
                    <mwt:SystemDropShadowChrome.BitmapEffect>
                        <DropShadowBitmapEffect Color="#FFB3C7E5" Direction="-60" ShadowDepth="5" Opacity="0.8"/>
                    </mwt:SystemDropShadowChrome.BitmapEffect>
                    <Border BorderThickness="1,1,1,1" BorderBrush="#FF959595" Background="#FFF5F5F5" Name="SubMenuBorder">
                        <ScrollViewer Style="{DynamicResource {ComponentResourceKey TypeInTargetAssembly=FrameworkElement, ResourceId=MenuScrollViewer}}" Name="SubMenuScrollViewer" Margin="1,0,1,0">
                            <Grid RenderOptions.ClearTypeHint="Enabled">
                                <Canvas Width="0" Height="0" HorizontalAlignment="Left" VerticalAlignment="Top">
                                    <Rectangle Fill="#FFF5F5F5" Name="OpaqueRect" Width="Auto" Height="Auto" />
                                </Canvas>
                                <Rectangle RadiusX="2" RadiusY="2" Fill="#FFF1F1F1" Width="28" Margin="1,2,1,2" HorizontalAlignment="Left" />
                                <Rectangle Fill="#FFE2E3E3" Width="1" Margin="29,2,0,2" HorizontalAlignment="Left" />
                                <Rectangle Fill="#FFFFFFFF" Width="1" Margin="30,2,0,2" HorizontalAlignment="Left" />
                                <ItemsPresenter Name="ItemsPresenter" Margin="2,2,2,2" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" KeyboardNavigation.TabNavigation="Cycle" KeyboardNavigation.DirectionalNavigation="Cycle" Grid.IsSharedSizeScope="True" />
                            </Grid>
                        </ScrollViewer>
                    </Border>
                </mwt:SystemDropShadowChrome>
            </Popup>
        </Grid>
        <ControlTemplate.Triggers>
            <Trigger Property="MenuItem.IsSuspendingPopupAnimation" Value="True">
                <Setter Property="Popup.PopupAnimation" TargetName="PART_Popup" Value="None" />
            </Trigger>
            <Trigger Property="MenuItem.IsHighlighted" Value="True">
                <Setter Property="Shape.Stroke" TargetName="InnerBorder" Value="#D1DBF4FF" />
            </Trigger>
            <Trigger Property="MenuItem.Icon" Value="{x:Null}">
                <Setter Property="UIElement.Visibility" TargetName="Icon" Value="Collapsed" />
            </Trigger>
            <Trigger Property="MenuItem.IsChecked" Value="True">
                <Setter Property="UIElement.Visibility" TargetName="GlyphPanel" Value="Visible" />
                <Setter Property="UIElement.Visibility" TargetName="Icon" Value="Collapsed" />
            </Trigger>
            <Trigger Property="Popup.HasDropShadow" SourceName="PART_Popup" Value="True">
                <Setter Property="FrameworkElement.Margin" TargetName="Shdw" Value="0,0,5,5" />
                <Setter Property="mwt:SystemDropShadowChrome.Color" TargetName="Shdw" Value="#71000000" />
            </Trigger>
            <Trigger Property="MenuItem.IsHighlighted" Value="True">
                <Setter Property="Shape.Fill" TargetName="Bg">
                    <Setter.Value>
                        <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                            <LinearGradientBrush.GradientStops>
                                <GradientStop Color="#34C5EBFF" Offset="0" />
                                <GradientStop Color="#3481D8FF" Offset="1" />
                            </LinearGradientBrush.GradientStops>
                        </LinearGradientBrush>
                    </Setter.Value>
                </Setter>
                <Setter Property="Shape.Stroke" TargetName="Bg" Value="#8571CBF1" />
            </Trigger>
            <Trigger Property="UIElement.IsEnabled" Value="False">
                <Setter Property="TextElement.Foreground" Value="#FF9A9A9A" />
                <Setter Property="Panel.Background" TargetName="GlyphPanel" Value="#FFEEE9E9" />
                <Setter Property="Border.BorderBrush" TargetName="GlyphPanel" Value="#FFDBD6D6" />
                <Setter Property="Shape.Fill" TargetName="Glyph" Value="#FF848589" />
            </Trigger>
            <Trigger Property="ScrollViewer.CanContentScroll" SourceName="SubMenuScrollViewer" Value="False">
                <Setter Property="Canvas.Top" TargetName="OpaqueRect" Value="{Binding Path=VerticalOffset, ElementName=SubMenuScrollViewer}" />
                <Setter Property="Canvas.Left" TargetName="OpaqueRect">
                    <Setter.Value>
                        <Binding Path="HorizontalOffset" ElementName="SubMenuScrollViewer" />
                    </Setter.Value>
                </Setter>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>

Usage:

    <ContextMenu x:Name="deleteContextMenu">
        <ContextMenu.BitmapEffect>
            <DropShadowBitmapEffect Color="#FFB3C7E5" Direction="-60" ShadowDepth="5" Opacity="0.8"/>
        </ContextMenu.BitmapEffect>

        <MenuItem Header="Delete" Name="DeleteMenuItem" Background="White" Template="{StaticResource miTest}">
            <MenuItem Header="DeleteChild" Name="DeleteMenuItem2" Background="White" Template="{StaticResource miTest}">
                <MenuItem Header="DeleteChild" Name="DeleteMenuItem3" Background="White" Template="{StaticResource miTest}">
                </MenuItem>
            </MenuItem>
        </MenuItem>
    </ContextMenu>

OTHER TIPS

You need to set the Style for the Submenu. Here is a MSDN example. Obviously, just take the code that you need.

http://msdn.microsoft.com/en-us/library/ms744758%28v=vs.85%29.aspx

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top