How to create menus in WPF with Microsoft Web Application style

We were commissioned to develop a corporate application in WPF, which will replace the Black Winforms application with linear control with a modern look.

We like the look of Microsoft web applications now:

enter image description here

We could create these menus in WPF in the usual way:

<DockPanel> <Menu DockPanel.Dock="Top"> <MenuItem Header="_File"> <MenuItem Header="_New" /> <MenuItem Header="_Open" /> <MenuItem Header="_Save" /> <Separator /> <MenuItem Header="_Exit" /> </MenuItem> </Menu> <TextBox AcceptsReturn="True" /> </DockPanel> 

But we get something similar to the Winforms menu.

I saw some impressive style efforts like this one , but they all seem to have the same familiar Winforms form. I also saw menus in libraries like Metro MahApps, but they attack us like Spartan ones.

Is the WPF menu control flexible enough to be styled as shown in the picture above, or should we go a different way, like creating a custom menu control from Stack Panels and Lists? What are the tradeoffs?

Bonus points (i.e. reward) will be awarded for xaml / code, which does just that.

An example of this menu style in action:
https://www.visualstudio.com/

+5
source share
5 answers

WPF was really designed with the ability to change the appearance and behavior of each of the ready-made mechanisms / controls (buttons, menus, tree structure, etc.). Therefore, in general, it is better to do this rather than rewrite everything. For example, if you change your user menu, you will have to think about the keyboard, UI automation, etc.

So, I took a picture on your example and tried to create a minimal working sample - pure XAML - which mimics the VS online menu (I also added a background color change, which is not the default in the WPF menu).

Here is the result and, as you can see, it looks very similar:

enter image description here

Here is the XAML. I chose to use a custom control template for each MenuItem. I think this is very practical when you really need to customize each item.

 <Window x:Class="WpfApp1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="550" Width="525"> <Window.Resources> <BooleanToVisibilityConverter x:Key="btv" /> <!-- style a top level menu item --> <ControlTemplate x:Key="VsMenuTop" TargetType="MenuItem"> <StackPanel TextBlock.FontSize="15px" Height="40"> <!-- label, icons, etc. --> <Label Content="{TemplateBinding Header}" Margin="5" Foreground="White" /> <!-- sub items --> <Popup IsOpen="{TemplateBinding IsSubmenuOpen}" AllowsTransparency="True" Focusable="False"> <Border BorderThickness="1" Background="White" BorderBrush="#E0E0E0"> <StackPanel IsItemsHost="True" /> </Border> </Popup> <StackPanel.Style> <Style TargetType="StackPanel"> <Style.Triggers> <Trigger Property="IsMouseOver" Value="True"> <Setter Property="Background" Value="#106EBE" /> </Trigger> </Style.Triggers> </Style> </StackPanel.Style> </StackPanel> </ControlTemplate> <!-- style a non-top level menu item --> <ControlTemplate x:Key="VsMenuSub" TargetType="MenuItem"> <DockPanel TextBlock.FontSize="15px" x:Name="panel"> <!-- label, icons, etc. --> <Image Source="{Binding Icon, RelativeSource={RelativeSource TemplatedParent}}" Width="20" Margin="5,0" /> <Label Content="{TemplateBinding Header}" Foreground="Black" Margin="0,5,5,5" /> <!-- draw the right arrow only if this menu item has sub items --> <Image Source="icon_right.png" Visibility="{Binding HasItems, Converter={StaticResource btv}, RelativeSource={RelativeSource TemplatedParent}}" /> <!-- sub items --> <Popup IsOpen="{TemplateBinding IsSubmenuOpen}" AllowsTransparency="True" Focusable="False" Placement="Right" > <Border BorderThickness="1" Background="White" BorderBrush="#E0E0E0"> <StackPanel IsItemsHost="True" /> </Border> </Popup> </DockPanel> <ControlTemplate.Triggers> <Trigger Property="IsHighlighted" Value="True"> <Setter Property="Background" TargetName="panel" Value="#EFF6FC" /> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> <!-- style the separator --> <ControlTemplate x:Key="VsMenuSep" TargetType="Separator"> <Border Height="1" Background="#E0E0E0" /> </ControlTemplate> <!-- style the VSOnline --> <ControlTemplate x:Key="VsOnline" TargetType="MenuItem"> <StackPanel TextBlock.FontSize="15px" Height="40" Orientation="Horizontal" Background="#005A9E"> <Label Content="{TemplateBinding Header}" Margin="5" Foreground="White" /> <Image Source="icon_down.png" Height="20" Margin="0,0,5,0" /> <!-- sub items --> <Popup IsOpen="{TemplateBinding IsSubmenuOpen}" AllowsTransparency="True" Focusable="False"> <Border BorderThickness="1" Background="White" BorderBrush="#E0E0E0"> <StackPanel IsItemsHost="True" /> </Border> </Popup> </StackPanel> </ControlTemplate> <!-- some base stuff --> <Style TargetType="Menu"> <Setter Property="Background" Value="#0078D7" /> <Setter Property="Height" Value="40px" /> </Style> </Window.Resources> <!-- the real app and real menu --> <StackPanel> <Menu IsMainMenu="True"> <MenuItem Header="_VSOnline" Template="{StaticResource VsOnline}" > <MenuItem Header="_Whatever" Template="{StaticResource VsMenuSub}" /> </MenuItem> <MenuItem Header="_Dashboards" Template="{StaticResource VsMenuTop}"> <MenuItem Header="_Overview" Template="{StaticResource VsMenuSub}" /> </MenuItem> <MenuItem Header="_Code" Template="{StaticResource VsMenuTop}"> <MenuItem Header="_Files" Template="{StaticResource VsMenuSub}" /> <MenuItem Header="_Commits" Template="{StaticResource VsMenuSub}" /> <MenuItem Header="_Pushes" Template="{StaticResource VsMenuSub}" /> </MenuItem> <MenuItem Header="_Work" Template="{StaticResource VsMenuTop}"> <MenuItem Header="_Backlogs" Template="{StaticResource VsMenuSub}" Icon="icon_backlogs.png" /> <MenuItem Header="_Queries" Template="{StaticResource VsMenuSub}" Icon="icon_queries.png" /> <Separator Template="{StaticResource VsMenuSep}" /> <MenuItem Header="_New Work Item" Template="{StaticResource VsMenuSub}"> <MenuItem Header="_Epic" Template="{StaticResource VsMenuSub}" Icon="icon_epic.png" /> <MenuItem Header="_Feature" Template="{StaticResource VsMenuSub}" Icon="icon_feature.png" /> <MenuItem Header="_Issue" Template="{StaticResource VsMenuSub}" Icon="icon_issue.png" /> <MenuItem Header="_Task" Template="{StaticResource VsMenuSub}" Icon="icon_task.png" /> <MenuItem Header="_Test Case" Template="{StaticResource VsMenuSub}" Icon="icon_testcase.png" /> <MenuItem Header="_User Story" Template="{StaticResource VsMenuSub}" Icon="icon_userstory.png" /> </MenuItem> <MenuItem Header="_Bug" Template="{StaticResource VsMenuSub}" Icon="icon_bug.png" /> </MenuItem> </Menu> </StackPanel> </Window> 

The project is available here on github .

+4
source

You are probably looking for a Wpf theme to get you started.

Such as http://brianlagunas.com/free-metro-light-and-dark-themes-for-wpf-and-silverlight-microsoft-controls/ or take a look at this answer SO: Any free WPF themes?

Then you probably want to customize it even more with the look and style you are looking for.

+3
source

This is the default menu, but white, you can change the background color, text font, height and everything else you want only by editing this style.

Here is your MainWindow.xaml

 <Menu IsMainMenu="True" HorizontalContentAlignment="Left" Background="Transparent" > <MenuItem Header="File" HorizontalContentAlignment="Left" > <MenuItem Header="Menu Item 01" Command="{Binding MenuCommand}" CommandParameter="Param01" > <MenuItem.Icon> <Image Source="Images/settings.png" Height="20"/> </MenuItem.Icon> </MenuItem> <MenuItem Header="Menu Item 02" Command="{Binding MenuCommand}" CommandParameter="Param02" > <MenuItem.Icon> <Image Source="Images/settings.png" Height="20"/> </MenuItem.Icon> </MenuItem> <Separator /> <MenuItem Header="LogOff" Command="{Binding MenuCommand}" CommandParameter="LogOff" > <MenuItem.Icon> <Image Source="Images/logoff.png" Height="20"/> </MenuItem.Icon> </MenuItem> </MenuItem> </Menu> 

in the app.xaml file

 <!-- Menu Begin --> <!-- Menu --> <Style TargetType="{x:Type Menu}"> <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.MenuBarBrushKey}}"/> <Setter Property="FontFamily" Value="{DynamicResource {x:Static SystemFonts.MenuFontFamilyKey}}"/> <Setter Property="FontSize" Value="{DynamicResource {x:Static SystemFonts.MenuFontSizeKey}}"/> <Setter Property="FontStyle" Value="{DynamicResource {x:Static SystemFonts.MenuFontStyleKey}}"/> <Setter Property="FontWeight" Value="{DynamicResource {x:Static SystemFonts.MenuFontWeightKey}}"/> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.MenuTextBrushKey}}"/> <Setter Property="VerticalContentAlignment" Value="Center"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type Menu}"> <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true"> <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> <!-- Level 0 --> <ControlTemplate x:Key="{x:Static MenuItem.TopLevelItemTemplateKey}" TargetType="{x:Type MenuItem}"> <Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True"> <Grid x:Name="Grid" VerticalAlignment="Center"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <ContentPresenter x:Name="Icon" Content="{TemplateBinding Icon}" ContentSource="Icon" HorizontalAlignment="Center" Height="16" Margin="3" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Width="16" Visibility="Collapsed"/> <Path x:Name="GlyphPanel" Data="F1M10,1.2L4.7,9.1 4.5,9.1 0,5.2 1.3,3.5 4.3,6.1 8.3,0 10,1.2z" Fill="{TemplateBinding Foreground}" FlowDirection="LeftToRight" Margin="3" Visibility="Collapsed" VerticalAlignment="Center"/> <ContentPresenter x:Name="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" > <Border x:Name="SubMenuBorder" BorderBrush="#FF999999" BorderThickness="1" Background="White" Padding="2"> <ScrollViewer x:Name="SubMenuScrollViewer" Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}"> <Grid x:Name="Grid1" RenderOptions.ClearTypeHint="Enabled"> <Canvas x:Name="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> <Rectangle x:Name="Rectangle" Fill="Transparent" HorizontalAlignment="Left" Margin="29,2,0,2" Width="1"/> <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="IsSuspendingPopupAnimation" Value="True"> <Setter Property="PopupAnimation" TargetName="PART_Popup" Value="None"/> </Trigger> <Trigger Property="Icon" Value="{x:Null}"> <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/> </Trigger> <Trigger Property="IsChecked" Value="True"> <Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/> <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/> </Trigger> <Trigger Property="IsHighlighted" Value="True"> <Setter Property="Background" TargetName="templateRoot" Value="#3D26A0DA"/> <Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF26A0DA"/> </Trigger> <Trigger Property="IsEnabled" Value="False"> <Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="#FF707070"/> <Setter Property="Fill" TargetName="GlyphPanel" Value="#FF707070"/> </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> </ControlTemplate.Triggers> </ControlTemplate> <!-- Level 0 --> <ControlTemplate x:Key="{x:Static MenuItem.TopLevelHeaderTemplateKey}" TargetType="{x:Type MenuItem}"> <Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True"> <Grid x:Name="Grid" VerticalAlignment="Center"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <ContentPresenter x:Name="Icon" Content="{TemplateBinding Icon}" ContentSource="Icon" HorizontalAlignment="Center" Height="16" Margin="3" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Width="16" Visibility="Collapsed"/> <Path x:Name="GlyphPanel" Data="F1M10,1.2L4.7,9.1 4.5,9.1 0,5.2 1.3,3.5 4.3,6.1 8.3,0 10,1.2z" Fill="{TemplateBinding Foreground}" FlowDirection="LeftToRight" Margin="3" Visibility="Collapsed" VerticalAlignment="Center"/> <ContentPresenter x:Name="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" > <Border x:Name="SubMenuBorder" BorderBrush="#FF999999" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.MenuColorKey}}" Padding="2"> <ScrollViewer x:Name="SubMenuScrollViewer" Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}"> <Grid x:Name="Grid1" RenderOptions.ClearTypeHint="Enabled"> <Canvas x:Name="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> <Rectangle x:Name="Rectangle" Fill="Transparent" HorizontalAlignment="Left" Margin="29,2,0,2" Width="1"/> <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="IsSuspendingPopupAnimation" Value="True"> <Setter Property="PopupAnimation" TargetName="PART_Popup" Value="None"/> </Trigger> <Trigger Property="Icon" Value="{x:Null}"> <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/> </Trigger> <Trigger Property="IsChecked" Value="True"> <Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/> <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/> </Trigger> <Trigger Property="IsHighlighted" Value="True"> <Setter Property="Background" TargetName="templateRoot" Value="#3D26A0DA"/> <Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF26A0DA"/> </Trigger> <Trigger Property="IsEnabled" Value="False"> <Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="#FF707070"/> <Setter Property="Fill" TargetName="GlyphPanel" Value="#FF707070"/> </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> </ControlTemplate.Triggers> </ControlTemplate> <!-- Level 1,2,3,4,... --> <ControlTemplate x:Key="{x:Static MenuItem.SubmenuHeaderTemplateKey}" TargetType="{x:Type MenuItem}"> <Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True"> <Grid Margin="-1"> <Grid.ColumnDefinitions> <ColumnDefinition MinWidth="22" SharedSizeGroup="MenuItemIconColumnGroup" Width="Auto"/> <ColumnDefinition Width="13"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="30"/> <ColumnDefinition SharedSizeGroup="MenuItemIGTColumnGroup" Width="Auto"/> <ColumnDefinition Width="20"/> </Grid.ColumnDefinitions> <ContentPresenter x:Name="Icon" Content="{TemplateBinding Icon}" ContentSource="Icon" HorizontalAlignment="Center" Height="16" Margin="3" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Width="16"/> <Border x:Name="GlyphPanel" BorderBrush="#FF26A0DA" BorderThickness="1" Background="#3D26A0DA" Height="22" Margin="-1,0,0,0" Visibility="Hidden" VerticalAlignment="Center" Width="22" > <Path x:Name="Glyph" Data="{DynamicResource ลง}" Fill="#FF212121" FlowDirection="LeftToRight" Height="11" Width="9"/> </Border> <ContentPresenter ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.Column="2" ContentStringFormat="{TemplateBinding HeaderStringFormat}" ContentSource="Header" HorizontalAlignment="Left" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center"/> <TextBlock Grid.Column="4" Margin="{TemplateBinding Padding}" Opacity="0.7" Text="{TemplateBinding InputGestureText}" VerticalAlignment="Center"/> <Path x:Name="RightArrow" Grid.Column="5" Data="M0,0L4,3.5 0,7z" Fill="#FF212121" HorizontalAlignment="Left" Margin="10,0,0,0" VerticalAlignment="Center"/> <Popup x:Name="PART_Popup" AllowsTransparency="True" Focusable="False" HorizontalOffset="-2" IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}" Placement="Right" VerticalOffset="-3"> <Border x:Name="SubMenuBorder" BorderBrush="#FF999999" BorderThickness="1" Background="{DynamicResource {x:Static SystemColors.MenuColorKey}}" 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"> <!--Fill="{Binding Background, ElementName=SubMenuBorder}" White #FFF0F0F0--> <Rectangle x:Name="OpaqueRect" Fill="{Binding Background, ElementName=SubMenuBorder}" Height="{Binding ActualHeight, ElementName=SubMenuBorder}" Width="{Binding ActualWidth, ElementName=SubMenuBorder}"/> </Canvas> <Rectangle Fill="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" HorizontalAlignment="Left" Margin="29,2,0,2" Width="1"/> <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="IsSuspendingPopupAnimation" Value="True"> <Setter Property="PopupAnimation" TargetName="PART_Popup" Value="None"/> </Trigger> <Trigger Property="Icon" Value="{x:Null}"> <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/> </Trigger> <Trigger Property="IsChecked" Value="True"> <Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/> <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/> </Trigger> <Trigger Property="IsHighlighted" Value="True"> <Setter Property="Background" TargetName="templateRoot" Value="Transparent"/> <Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF26A0DA"/> </Trigger> <Trigger Property="IsEnabled" Value="False"> <Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="#FF707070"/> <Setter Property="Fill" TargetName="Glyph" Value="#FF707070"/> <Setter Property="Fill" TargetName="RightArrow" Value="#FF707070"/> </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> </ControlTemplate.Triggers> </ControlTemplate> <!-- Level 1,2,3,4,... --> <ControlTemplate x:Key="{x:Static MenuItem.SubmenuItemTemplateKey}" TargetType="{x:Type MenuItem}"> <Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True"> <Grid Margin="-1"> <Grid.ColumnDefinitions> <ColumnDefinition MinWidth="22" SharedSizeGroup="MenuItemIconColumnGroup" Width="Auto"/> <ColumnDefinition Width="13"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="30"/> <ColumnDefinition SharedSizeGroup="MenuItemIGTColumnGroup" Width="Auto"/> <ColumnDefinition Width="20"/> </Grid.ColumnDefinitions> <ContentPresenter x:Name="Icon" Content="{TemplateBinding Icon}" ContentSource="Icon" HorizontalAlignment="Center" Height="16" Margin="3" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center" Width="16"/> <Border x:Name="GlyphPanel" BorderBrush="#FF26A0DA" BorderThickness="1" Background="#3D26A0DA" ClipToBounds="False" HorizontalAlignment="Center" Height="22" Margin="-1,0,0,0" Visibility="Hidden" VerticalAlignment="Center" Width="22"> <Path x:Name="Glyph" Data="F1M10,1.2L4.7,9.1 4.5,9.1 0,5.2 1.3,3.5 4.3,6.1 8.3,0 10,1.2z" Fill="#FF212121" FlowDirection="LeftToRight" Height="11" Width="10"/> </Border> <ContentPresenter x:Name="menuHeaderContainer" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.Column="2" ContentStringFormat="{TemplateBinding HeaderStringFormat}" ContentSource="Header" HorizontalAlignment="Left" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Center"/> <TextBlock x:Name="menuGestureText" Grid.Column="4" Margin="{TemplateBinding Padding}" Opacity="0.7" Text="{TemplateBinding InputGestureText}" VerticalAlignment="Center"/> </Grid> </Border> <ControlTemplate.Triggers> <Trigger Property="Icon" Value="{x:Null}"> <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/> </Trigger> <Trigger Property="IsChecked" Value="True"> <Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/> <Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/> </Trigger> <Trigger Property="IsHighlighted" Value="True"> <Setter Property="Background" TargetName="templateRoot" Value="#3D26A0DA"/> <Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF26A0DA"/> </Trigger> <Trigger Property="IsEnabled" Value="False"> <Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="#FF707070"/> <Setter Property="Fill" TargetName="Glyph" Value="#FF707070"/> </Trigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsHighlighted" Value="True"/> <Condition Property="IsEnabled" Value="False"/> </MultiTrigger.Conditions> <Setter Property="Background" TargetName="templateRoot" Value="#0A000000"/> <Setter Property="BorderBrush" TargetName="templateRoot" Value="#21000000"/> </MultiTrigger> </ControlTemplate.Triggers> </ControlTemplate> <!-- Menu End --> 
+2
source

You can use something like: http://materialdesigninxaml.net

+2
source

I would create a menu using XAML

XAML pages are something like this:

 <Window.Resources> <Style TargetType="TextBlock"> <Setter Property="Margin" Value="10" /> <Setter Property="FontSize" Value="15" /> <Setter Property="Foreground" Value="White" /> </Style> </Window.Resources> <Grid x:Name="Content"> <Grid > <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <StackPanel Orientation="Horizontal" Background="CornflowerBlue"> <TextBlock Text="Menu1" MouseLeftButtonDown="OnMouseLeftButtonDown" /> <TextBlock Text="Menu2" MouseLeftButtonDown="OnMouseLeftButtonDown" /> <TextBlock Text="Menu3" MouseLeftButtonDown="OnMouseLeftButtonDown" /> </StackPanel> <Border Grid.Row="1" Background="Bisque"></Border> </Grid> </Grid> 

And in the code:

  private void OnMouseLeftButtonDown(object sender, MouseEventArgs e) { var textBlock = sender as TextBlock; if (textBlock == null) return; var relativePoint = VisualTreeHelper.GetOffset(textBlock);//textBlock.TransformToAncestor(Content).Transform(new Point(0, 0)); //Almost invisible Background - If the user clicks it the menu is hidden var back = new Border{Background = new SolidColorBrush(Color.FromArgb(1,255,255,255))}; back.MouseLeftButtonDown += (o, args) => { Content.Children.Remove(back.Tag as UIElement); Content.Children.Remove(back); }; Content.Children.Add(back); //Build menu var menu = new Border{Background = new SolidColorBrush(Colors.White), Width = 200, Height = 500, BorderBrush = new SolidColorBrush(Colors.Gray), BorderThickness = new Thickness(1), HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top}; back.Tag = menu; menu.RenderTransform = new TranslateTransform(relativePoint.X, relativePoint.Y + textBlock.ActualHeight + 5); //Do some more styling //Fill Menu here according to the tag of the TextBlock (switch(textBlock.Tag){...} or use a predefined view Content.Children.Add(menu); //Hide the Menu on click - TODO Implement logic to hide menu if a MenuItem was clicked... menu.MouseLeftButtonDown += (o, args) => { Content.Children.Remove(back.Tag as UIElement); Content.Children.Remove(back); }; } 

OK, this is a very simple example and needs a lot of improvement, but I think you can work on it ...

0
source

Source: https://habr.com/ru/post/1273752/


All Articles