I used the code form the answer from this question to build my own itemmenu.
The problem is that the top-most-item should only have an icon as content. but if I do this, the icon is not displayed, unless I also set isCheckable=true.
This is the code that I changed sightly.
<ControlTemplate TargetType="{x:Type MenuItem}">
<Border x:Name="Border"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Col0" MinWidth="17" Width="Auto" SharedSizeGroup="MenuItemIconColumnGroup"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="MenuTextColumnGroup"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="MenuItemIGTColumnGroup"/>
<ColumnDefinition x:Name="Col3" Width="14"/>
</Grid.ColumnDefinitions>
<!-- ContentPresenter to show an Icon if needed -->
<ContentPresenter Grid.Column="0" Margin="4,0,6,0" x:Name="Icon" VerticalAlignment="Center" ContentSource="Icon"/>
<!-- Glyph is a checkmark if needed for a checkable menu -->
<Grid Grid.Column="0" Visibility="Hidden" Margin="4,0,6,0" x:Name="GlyphPanel" VerticalAlignment="Center">
<Path x:Name="GlyphPanelpath" VerticalAlignment="Center" Fill="{TemplateBinding Foreground}" Data="M0,2 L0,4.8 L2.5,7.4 L7.1,2.8 L7.1,0 L2.5,4.6 z" FlowDirection="LeftToRight"/>
</Grid>
<!-- Content for the menu text etc -->
<ContentPresenter Grid.Column="1"
Margin="{TemplateBinding Padding}"
x:Name="HeaderHost"
RecognizesAccessKey="True"
ContentSource="Header"/>
<!-- Content for the menu IGT -->
<ContentPresenter Grid.Column="2"
Margin="8,1,8,1"
x:Name="IGTHost"
ContentSource="InputGestureText"
VerticalAlignment="Center"/>
<!-- Arrow drawn path which points to the next level of the menu -->
<Grid Grid.Column="3" Margin="4,0,6,0" x:Name="ArrowPanel" VerticalAlignment="Center">
<Path x:Name="ArrowPanelPath" HorizontalAlignment="Right" VerticalAlignment="Center" Fill="{TemplateBinding Foreground}" Data="M0,0 L0,8 L4,4 z"/>
</Grid>
<!-- The Popup is the body of the menu which expands down or across depending on the level of the item -->
<Popup IsOpen="{Binding Path=IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" Placement="Right" x:Name="SubMenuPopup" Focusable="false" PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}">
<Border x:Name="SubMenuBorder" BorderBrush="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type Menu}}}" BorderThickness="1" Padding="2,2,2,2">
<Grid x:Name="SubMenu" Grid.IsSharedSizeScope="True">
<!-- StackPanel holds children of the menu. This is set by IsItemsHost=True -->
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle"/>
</Grid>
</Border>
</Popup>
</Grid>
</Border>
<!-- These triggers re-configure the four arrangements of MenuItem to show different levels of menu via Role -->
<ControlTemplate.Triggers>
<!-- Role = TopLevelHeader : this is the root menu item in a menu; the Popup expands down -->
<Trigger Property="Role" Value="TopLevelHeader">
<Setter Property="Padding" Value="6,1,6,1"/>
<Setter Property="Placement" Value="Bottom" TargetName="SubMenuPopup"/>
<Setter Property="MinWidth" Value="0" TargetName="Col0"/>
<Setter Property="Width" Value="Auto" TargetName="Col3"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="Icon"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="GlyphPanel"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="IGTHost"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="ArrowPanel"/>
</Trigger>
<!-- Role = TopLevelItem : this is a child menu item from the top level without any child items-->
<Trigger Property="Role" Value="TopLevelItem">
<Setter Property="Padding" Value="6,1,6,1"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="ArrowPanel"/>
</Trigger>
<!-- Role = SubMenuHeader : this is a child menu item which does not have children -->
<Trigger Property="Role" Value="SubmenuHeader">
<Setter Property="DockPanel.Dock" Value="Top"/>
<Setter Property="Padding" Value="0,2,0,2"/>
</Trigger>
<!-- Role = SubMenuItem : this is a child menu item which has children-->
<Trigger Property="Role" Value="SubmenuItem">
<Setter Property="DockPanel.Dock" Value="Top"/>
<Setter Property="Padding" Value="0,2,0,2"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="ArrowPanel"/>
</Trigger>
<Trigger Property="IsSuspendingPopupAnimation" Value="true">
<Setter Property="PopupAnimation" Value="None" TargetName="SubMenuPopup"/>
</Trigger>
<!-- If no Icon is present the we collapse the Icon Content -->
<Trigger Property="Icon" Value="{x:Null}">
<Setter Property="Visibility" Value="Collapsed" TargetName="Icon"/>
</Trigger>
<!-- The GlyphPanel contains the CheckMark -->
<Trigger Property="IsChecked" Value="true">
<Setter Property="Visibility" Value="Visible" TargetName="GlyphPanel"/>
<Setter Property="Visibility" Value="Collapsed" TargetName="Icon"/>
</Trigger>
<!-- Using the system colors for the Menu Highlight and IsEnabled-->
<Trigger Property="IsHighlighted" Value="true">
<Setter Property="Background" Value="{StaticResource HighlightedBackgroundBrush}" TargetName="Border"/>
<Setter Property="Foreground" Value="{StaticResource HighlightedText}"/>
<Setter Property="BorderBrush" Value="{StaticResource NormalBorderBrush}" TargetName="Border"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="false">
<Setter Property="Background" Value="{StaticResource MenuBackgroundBrush}" TargetName="Border"/>
<Setter Property="Foreground" Value="{StaticResource SolidMenuFontBrush}"/>
<Setter Property="BorderBrush" Value="{StaticResource MenuBackgroundBrush}" TargetName="Border"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="LightGray"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
In the actual UserControl the menuitems are used like this:
<Menu x:Name="myMenu" Grid.Row="0" Grid.Column="1" >
<MenuItem Height="25" Width="30" Header="" IsCheckable="True">
<MenuItem.Icon>
<Image Source="/Tool;component/Resources/help.png" Stretch="Fill" Height="20" Width="20"/>
</MenuItem.Icon>
<MenuItem x:Name="btAbout" Header="About" />
<MenuItem x:Name="btHelp" Header="Documentation" />
<MenuItem x:Name="btBugReport" Header="Bug report" />
<MenuItem x:Name="btFeatureRequest" Header="Feature request" />
</MenuItem>
</Menu>
What changes are necessary so that the Icon is always displayed?
I don't see the IsCheckable property anywhere in your Control Template, but your problem is probably related with both the Icon and the GlyphPanel (for the check mark) being on the same Grid.Column.
Add a new ColumnDefinition to the Grid for your Icon:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="MenuCustomIconColumnGroup" />
<ColumnDefinition x:Name="Col0" MinWidth="17" Width="Auto" SharedSizeGroup="MenuItemIconColumnGroup"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="MenuTextColumnGroup"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="MenuItemIGTColumnGroup"/>
<ColumnDefinition x:Name="Col3" Width="14"/>
</Grid.ColumnDefinitions>
And set the Grid.Row values accordingly for all the affected controls. For instance:
<!-- Glyph is a checkmark if needed for a checkable menu -->
<Grid Grid.Column="1" Visibility="Hidden" Margin="4,0,6,0" x:Name="GlyphPanel" VerticalAlignment="Center">
Related
So I am curious to why the scrollviewers repeatbutton at the bottom is white, it should be transparent, I didnt notice this until I resized my scrollviewer to fit perfectly, how do I change it's color to transparent?
I was looking throught the
RepeatButton part of the style and tried changing the background property but that didn't work either, it did nothing.
I even tried hiding it like so
<RepeatButton x:Name="PageDown"
Command="ScrollBar.PageUpCommand"
Opacity="0"
Focusable="false"
Visibility="Hidden"/>
But that didnt work either, it was still there.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="ScrollBarTrackThumb"
TargetType="{x:Type Thumb}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Thumb}">
<Grid x:Name="Grid">
<Rectangle HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Width="Auto"
Height="Auto"
Fill="Transparent" />
<Border x:Name="CornerScrollBarRectangle"
CornerRadius="5"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Width="Auto"
Height="Auto"
Margin="0,1,0,1"
Background="{TemplateBinding Background}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Tag"
Value="Horizontal">
<Setter TargetName="CornerScrollBarRectangle"
Property="Width"
Value="Auto" />
<Setter Property="Background" Value="Transparent"/>
<Setter TargetName="CornerScrollBarRectangle"
Property="Height"
Value="6" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type ScrollBar}">
<Setter Property="Stylus.IsFlicksEnabled"
Value="false" />
<Setter Property="Foreground"
Value="#ADABAB" />
<Setter Property="Background"
Value="Transparent" />
<Setter Property="Width"
Value="7" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollBar}">
<Grid x:Name="GridRoot"
Width="7"
Background="{TemplateBinding Background}">
<Grid.RowDefinitions>
<RowDefinition Height="0.00001*" />
</Grid.RowDefinitions>
<Track x:Name="PART_Track"
Grid.Row="0"
IsDirectionReversed="true"
Focusable="false">
<Track.Thumb>
<Thumb x:Name="Thumb"
Background="{TemplateBinding Foreground}"
Style="{DynamicResource ScrollBarTrackThumb}" />
</Track.Thumb>
<Track.IncreaseRepeatButton>
<RepeatButton x:Name="PageUp"
Command="ScrollBar.PageDownCommand"
Opacity="0"
Focusable="false"/>
</Track.IncreaseRepeatButton>
<Track.DecreaseRepeatButton>
<RepeatButton x:Name="PageDown"
Command="ScrollBar.PageUpCommand"
Opacity="0"
Focusable="false" />
</Track.DecreaseRepeatButton>
</Track>
</Grid>
<ControlTemplate.Triggers>
<Trigger SourceName="Thumb"
Property="IsMouseOver"
Value="true">
<Setter Value="{DynamicResource ButtonSelectBrush}"
TargetName="Thumb"
Property="Background" />
</Trigger>
<Trigger SourceName="Thumb"
Property="IsDragging"
Value="true">
<Setter Value="{DynamicResource DarkBrush}"
TargetName="Thumb"
Property="Background" />
</Trigger>
<Trigger Property="IsEnabled"
Value="false">
<Setter TargetName="Thumb"
Property="Visibility"
Value="Collapsed" />
</Trigger>
<Trigger Property="Orientation"
Value="Horizontal">
<Setter TargetName="GridRoot"
Property="LayoutTransform">
<Setter.Value>
<RotateTransform Angle="-90" />
</Setter.Value>
</Setter>
<Setter TargetName="PART_Track"
Property="LayoutTransform">
<Setter.Value>
<RotateTransform Angle="-90" />
</Setter.Value>
</Setter>
<Setter Property="Width"
Value="Auto" />
<Setter Property="Height"
Value="8" />
<Setter TargetName="Thumb"
Property="Tag"
Value="Horizontal" />
<Setter TargetName="PageDown"
Property="Command"
Value="ScrollBar.PageLeftCommand" />
<Setter TargetName="PageUp"
Property="Command"
Value="ScrollBar.PageRightCommand" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
And the actual scrollviewer
<ScrollViewer Height="380"
Margin="10">
<ListView ItemsSource="{Binding MessageViewModel.Messages}"
x:Name="MyListView"
Background="Transparent"
BorderThickness="0"
Height="380">
<ListView.ItemTemplate>
<DataTemplate>
<WrapPanel>
<TextBlock Text="{Binding Message}"
FontFamily="Consolas"
Foreground="#61d73d"
TextWrapping="Wrap"/>
</WrapPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
like Klaus, I think the issue is not with your repeatButton. Rather, you see the (white) background through your repeatButton.
try putting a red rectangle just behind your scrollButton to see the outcome
or even better : use snoop to check this kind of issue.
but also, Clemens is right : style/template the scrollviewer inside the listView, rather than outside.
Here's an example where it is not working:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication2"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<TreeView HorizontalAlignment="Stretch">
<TreeViewItem Header="Stuff" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch">
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0">Some random text</Label>
<TextBox Grid.Column="1"></TextBox>
</Grid>
</TreeViewItem>
</TreeView>
</Window>
I want the text box to stretch to the width of the window, but instead you get this:
The textbox expands as you type, which is not what I want.
I am thinking now it might be possible to set a binding on the width of the 2nd column to the width of the TreeViewItem but I'm not sure how to do that.
I've tried putting the grid in assorted panels, but that doesn't work either. I have also set the HorizontalAlignment and HorizontalContentAlignment to Stretch on the textbox itself, but that also doesn't work.
Is this some limitation of the Grid control? Putting a textbox in a tree view by itself will make it expand as I want, but I need the label to be next to it and if there are multiple fields it looks MUCH better if all the textboxes are aligned.
UPDATE
Using a different ControlTemplate allows headers to stretch but contents still don't stretch.
<TreeView HorizontalAlignment="Stretch">
<TreeViewItem Style="{DynamicResource StretchableTreeViewItemTemplate}" HorizontalAlignment="Stretch" Header="Stuff">
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0">Some random text</Label>
<TextBox Grid.Column="1" HorizontalAlignment="Stretch"></TextBox>
</Grid>
</TreeViewItem>
</TreeView>
<Style x:Key="StretchableTreeViewItemTemplate" TargetType="TreeViewItem"
BasedOn="{StaticResource {x:Type TreeViewItem}}">
<Setter Property="HorizontalContentAlignment"
Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TreeViewItem">
<StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"
MinWidth="19" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<!--
Note that the following do not work, but I believe the top 2 should?!
<ToggleButton IsChecked="{TemplateBinding IsExpanded}" ClickMode="Press" Name="Expander">
<ToggleButton IsChecked="{TemplateBinding Property=IsExpanded}" ClickMode="Press" Name="Expander">
<ToggleButton IsChecked="{TemplateBinding Path=IsExpanded}" ClickMode="Press" Name="Expander">
-->
<ToggleButton IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press"
Name="Expander">
<ToggleButton.Style>
<Style TargetType="ToggleButton">
<Setter Property="UIElement.Focusable"
Value="false" />
<Setter Property="FrameworkElement.Width"
Value="16" />
<Setter Property="FrameworkElement.Height"
Value="16" />
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border Padding="5,5,5,5"
Background="#00FFFFFF"
Width="16"
Height="16">
<Path Fill="#00FFFFFF"
Stroke="#FF989898"
Name="ExpandPath">
<Path.Data>
<PathGeometry Figures="M0,0L0,6L6,0z" />
</Path.Data>
<Path.RenderTransform>
<RotateTransform Angle="135"
CenterX="3"
CenterY="3" />
</Path.RenderTransform>
</Path>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="UIElement.IsMouseOver"
Value="True">
<Setter TargetName="ExpandPath"
Property="Shape.Stroke"
Value="#FF1BBBFA" />
<Setter TargetName="ExpandPath"
Property="Shape.Fill"
Value="#00FFFFFF" />
</Trigger>
<Trigger Property="ToggleButton.IsChecked"
Value="True">
<Setter TargetName="ExpandPath"
Property="UIElement.RenderTransform">
<Setter.Value>
<RotateTransform Angle="180"
CenterX="3"
CenterY="3" />
</Setter.Value>
</Setter>
<Setter TargetName="ExpandPath"
Property="Shape.Fill"
Value="#FF595959" />
<Setter TargetName="ExpandPath"
Property="Shape.Stroke"
Value="#FF262626" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ToggleButton.Style>
</ToggleButton>
<Border x:Name="Bd"
HorizontalAlignment="Stretch"
BorderThickness="{TemplateBinding Border.BorderThickness}"
BorderBrush="{TemplateBinding Border.BorderBrush}"
Padding="{TemplateBinding Control.Padding}"
Background="{TemplateBinding Panel.Background}"
SnapsToDevicePixels="True"
Grid.Column="1">
<ContentPresenter x:Name="PART_Header"
Content="{TemplateBinding HeaderedContentControl.Header}"
ContentTemplate="{TemplateBinding HeaderedContentControl.HeaderTemplate}"
ContentStringFormat="{TemplateBinding HeaderedItemsControl.HeaderStringFormat}"
ContentTemplateSelector="{TemplateBinding HeaderedItemsControl.HeaderTemplateSelector}"
ContentSource="Header"
HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</Border>
<ItemsPresenter x:Name="ItemsHost"
Grid.Column="1"
Grid.Row="1" />
</Grid>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="TreeViewItem.IsExpanded"
Value="False">
<Setter TargetName="ItemsHost"
Property="UIElement.Visibility"
Value="Collapsed" />
</Trigger>
<Trigger Property="ItemsControl.HasItems"
Value="False">
<Setter TargetName="Expander"
Property="UIElement.Visibility"
Value="Hidden" />
</Trigger>
<Trigger Property="TreeViewItem.IsSelected"
Value="True">
<Setter TargetName="Bd"
Property="Panel.Background"
Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
<Setter Property="TextElement.Foreground"
Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="TreeViewItem.IsSelected"
Value="True" />
<Condition Property="Selector.IsSelectionActive"
Value="False" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd"
Property="Panel.Background"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
<Setter Property="TextElement.Foreground"
Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
</MultiTrigger>
<Trigger Property="UIElement.IsEnabled"
Value="False">
<Setter Property="TextElement.Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Results:
Trying with Pikoh's solution:
<local:StretchingTreeView HorizontalAlignment="Stretch">
<local:StretchingTreeViewItem HorizontalAlignment="Stretch" Header="Stuff">
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0">Some random text</Label>
<TextBox Grid.Column="1" HorizontalAlignment="Stretch"></TextBox>
</Grid>
</local:StretchingTreeViewItem>
</local:StretchingTreeView>
Try something like this:
<TextBox Grid.Column="1" Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type Grid}}, Mode=OneWay}"></TextBox>
Edit
Ok,i've found one solution Here. It basically creates a new class inheriting Treeview:
class StretchingTreeView : TreeView
{
protected override DependencyObject GetContainerForItemOverride()
{
return new StretchingTreeViewItem();
}
protected override bool IsItemItsOwnContainerOverride(object item)
{
return item is StretchingTreeViewItem;
}
}
class StretchingTreeViewItem : TreeViewItem
{
public StretchingTreeViewItem()
{
this.Loaded += new RoutedEventHandler(StretchingTreeViewItem_Loaded);
}
private void StretchingTreeViewItem_Loaded(object sender, RoutedEventArgs e)
{
// The purpose of this code is to stretch the Header Content all the way accross the TreeView.
if (this.VisualChildrenCount > 0)
{
Grid grid = this.GetVisualChild(0) as Grid;
if (grid != null && grid.ColumnDefinitions.Count == 3)
{
// Remove the middle column which is set to Auto and let it get replaced with the
// last column that is set to Star.
grid.ColumnDefinitions.RemoveAt(1);
}
}
}
protected override DependencyObject GetContainerForItemOverride()
{
return new StretchingTreeViewItem();
}
protected override bool IsItemItsOwnContainerOverride(object item)
{
return item is StretchingTreeViewItem;
}
}
Example usage:
<Window x:Class="WpfApplication2.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication2"
Title="Window2" Height="300" Width="300">
<Grid>
<local:StretchingTreeView HorizontalAlignment="Stretch" >
<local:StretchingTreeViewItem Header="Stuff" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" >
<Grid HorizontalAlignment="Stretch" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0">Some random text</Label>
<TextBox Grid.Column="1" ></TextBox>
</Grid>
</local:StretchingTreeViewItem>
</local:StretchingTreeView>
</Grid>
The core of the issue (and the way to fix it) is described here:
The default ControlTemplate for the TreeViewItem uses a grid of 3 columns x 2 rows, defined such that the content cannot stretch horizontally. The author also gives a modified style, that changes the grid so that the content can stretch.
Note that the modified style sets the HorizontalContentAlignment of TreeViewItem to Center, and that the ControlTemplate uses this property for aligning the content.
To achieve the desired effect, either set HorizontalContentAlignment to Stretch in the modified style, or override just that property on the TreeView (or specific TreeViewItems).
Missing the BasedOn="{StaticResource {x:Type TreeViewItem}}" part causes the TreeViewItem to revert to using the default ControlTemplate, with the non-stretchable grid.
<Style TargetType="TreeViewItem" BasedOn="{StaticResource {x:Type TreeViewItem}}">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
In a HierarchicalDataTemplate, the effect would be achieved by using the ItemContainerStyle property.
#pikoh's method of deriving from TreeView and TreeViewItem achieves the same, by modifying the grid from code.
Complete example:
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<Style TargetType="TreeViewItem" BasedOn="{StaticResource {x:Type TreeViewItem}}">
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TreeViewItem">
<StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"
MinWidth="19" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<!-- Note that the following do not work, but I believe the top 2 should?! -->
<ToggleButton IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}" ClickMode="Press" Name="Expander">
<ToggleButton.Style>
<Style TargetType="ToggleButton">
<Setter Property="UIElement.Focusable" Value="false" />
<Setter Property="FrameworkElement.Width" Value="16" />
<Setter Property="FrameworkElement.Height" Value="16" />
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border Padding="5,5,5,5" Background="#00FFFFFF" Width="16" Height="16">
<Path Fill="#00FFFFFF" Stroke="#FF989898" Name="ExpandPath">
<Path.Data>
<PathGeometry Figures="M0,0L0,6L6,0z" />
</Path.Data>
<Path.RenderTransform>
<RotateTransform Angle="135" CenterX="3" CenterY="3" />
</Path.RenderTransform>
</Path>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="UIElement.IsMouseOver" Value="True">
<Setter TargetName="ExpandPath" Property="Shape.Stroke" Value="#FF1BBBFA" />
<Setter TargetName="ExpandPath" Property="Shape.Fill" Value="#00FFFFFF" />
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="True">
<Setter TargetName="ExpandPath" Property="UIElement.RenderTransform">
<Setter.Value>
<RotateTransform Angle="180" CenterX="3" CenterY="3" />
</Setter.Value>
</Setter>
<Setter TargetName="ExpandPath" Property="Shape.Fill" Value="#FF595959" />
<Setter TargetName="ExpandPath" Property="Shape.Stroke" Value="#FF262626" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ToggleButton.Style>
</ToggleButton>
<Border x:Name="Bd"
HorizontalAlignment="Stretch"
BorderThickness="{TemplateBinding Border.BorderThickness}"
BorderBrush="{TemplateBinding Border.BorderBrush}"
Padding="{TemplateBinding Control.Padding}"
Background="{TemplateBinding Panel.Background}"
SnapsToDevicePixels="True"
Grid.Column="1">
<ContentPresenter x:Name="PART_Header"
Content="{TemplateBinding HeaderedContentControl.Header}"
ContentTemplate="{TemplateBinding HeaderedContentControl.HeaderTemplate}"
ContentStringFormat="{TemplateBinding HeaderedItemsControl.HeaderStringFormat}"
ContentTemplateSelector="{TemplateBinding HeaderedItemsControl.HeaderTemplateSelector}"
ContentSource="Header"
HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</Border>
<ItemsPresenter x:Name="ItemsHost" Grid.Column="1" Grid.Row="1" />
</Grid>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="TreeViewItem.IsExpanded" Value="False">
<Setter TargetName="ItemsHost" Property="UIElement.Visibility" Value="Collapsed" />
</Trigger>
<Trigger Property="ItemsControl.HasItems" Value="False">
<Setter TargetName="Expander" Property="UIElement.Visibility" Value="Hidden" />
</Trigger>
<Trigger Property="TreeViewItem.IsSelected" Value="True">
<Setter TargetName="Bd" Property="Panel.Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
<Setter Property="TextElement.Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="TreeViewItem.IsSelected" Value="True" />
<Condition Property="Selector.IsSelectionActive" Value="False" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd" Property="Panel.Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
<Setter Property="TextElement.Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
</MultiTrigger>
<Trigger Property="UIElement.IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<TreeView HorizontalAlignment="Stretch">
<TreeView.Resources>
<Style TargetType="TreeViewItem" BasedOn="{StaticResource {x:Type TreeViewItem}}">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</TreeView.Resources>
<TreeViewItem Header="Stuff" HorizontalAlignment="Stretch">
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0">Some random text</Label>
<TextBox Grid.Column="1"></TextBox>
</Grid>
</TreeViewItem>
</TreeView>
</Window>
Due to an odd design decision by Microsoft when creating WPF, tree items can't stretch without replacing the control template.
See http://leecampbell.blogspot.com/2009/01/horizontal-stretch-on-treeviewitems.html
The required style is:
<Style TargetType="TreeViewItem"
BasedOn="{StaticResource {x:Type TreeViewItem}}">
<Setter Property="HorizontalContentAlignment"
Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TreeViewItem">
<StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"
MinWidth="19" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<!--
Note that the following do not work, but I believe the top 2 should?!
<ToggleButton IsChecked="{TemplateBinding IsExpanded}" ClickMode="Press" Name="Expander">
<ToggleButton IsChecked="{TemplateBinding Property=IsExpanded}" ClickMode="Press" Name="Expander">
<ToggleButton IsChecked="{TemplateBinding Path=IsExpanded}" ClickMode="Press" Name="Expander">
-->
<ToggleButton IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press"
Name="Expander">
<ToggleButton.Style>
<Style TargetType="ToggleButton">
<Setter Property="UIElement.Focusable"
Value="false" />
<Setter Property="FrameworkElement.Width"
Value="16" />
<Setter Property="FrameworkElement.Height"
Value="16" />
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border Padding="5,5,5,5"
Background="#00FFFFFF"
Width="16"
Height="16">
<Path Fill="#00FFFFFF"
Stroke="#FF989898"
Name="ExpandPath">
<Path.Data>
<PathGeometry Figures="M0,0L0,6L6,0z" />
</Path.Data>
<Path.RenderTransform>
<RotateTransform Angle="135"
CenterX="3"
CenterY="3" />
</Path.RenderTransform>
</Path>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="UIElement.IsMouseOver"
Value="True">
<Setter TargetName="ExpandPath"
Property="Shape.Stroke"
Value="#FF1BBBFA" />
<Setter TargetName="ExpandPath"
Property="Shape.Fill"
Value="#00FFFFFF" />
</Trigger>
<Trigger Property="ToggleButton.IsChecked"
Value="True">
<Setter TargetName="ExpandPath"
Property="UIElement.RenderTransform">
<Setter.Value>
<RotateTransform Angle="180"
CenterX="3"
CenterY="3" />
</Setter.Value>
</Setter>
<Setter TargetName="ExpandPath"
Property="Shape.Fill"
Value="#FF595959" />
<Setter TargetName="ExpandPath"
Property="Shape.Stroke"
Value="#FF262626" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ToggleButton.Style>
</ToggleButton>
<Border x:Name="Bd"
HorizontalAlignment="Stretch"
BorderThickness="{TemplateBinding Border.BorderThickness}"
BorderBrush="{TemplateBinding Border.BorderBrush}"
Padding="{TemplateBinding Control.Padding}"
Background="{TemplateBinding Panel.Background}"
SnapsToDevicePixels="True"
Grid.Column="1">
<ContentPresenter x:Name="PART_Header"
Content="{TemplateBinding HeaderedContentControl.Header}"
ContentTemplate="{TemplateBinding HeaderedContentControl.HeaderTemplate}"
ContentStringFormat="{TemplateBinding HeaderedItemsControl.HeaderStringFormat}"
ContentTemplateSelector="{TemplateBinding HeaderedItemsControl.HeaderTemplateSelector}"
ContentSource="Header"
HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</Border>
<ItemsPresenter x:Name="ItemsHost"
Grid.Column="1"
Grid.Row="1" />
</Grid>
</StackPanel>
<ControlTemplate.Triggers>
<Trigger Property="TreeViewItem.IsExpanded"
Value="False">
<Setter TargetName="ItemsHost"
Property="UIElement.Visibility"
Value="Collapsed" />
</Trigger>
<Trigger Property="ItemsControl.HasItems"
Value="False">
<Setter TargetName="Expander"
Property="UIElement.Visibility"
Value="Hidden" />
</Trigger>
<Trigger Property="TreeViewItem.IsSelected"
Value="True">
<Setter TargetName="Bd"
Property="Panel.Background"
Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
<Setter Property="TextElement.Foreground"
Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="TreeViewItem.IsSelected"
Value="True" />
<Condition Property="Selector.IsSelectionActive"
Value="False" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd"
Property="Panel.Background"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
<Setter Property="TextElement.Foreground"
Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
</MultiTrigger>
<Trigger Property="UIElement.IsEnabled"
Value="False">
<Setter Property="TextElement.Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
It seems like Grid's HorizontalAlignment Issue. I've tried it in .Net Framework 4 and it all works fine. Seems like in 4.5 even though you specify HorizontalAlignment as Stretch, it actually doesn't stretch it. So you can do a binding like below:
<Grid HorizontalAlignment="Stretch"
Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}},Path=ActualWidth,Mode=OneTime}"
>
Cause you can see in the run time that TreeViewItem has Width expected but Grid doesn't.
All you need to do is add Grid.ColumnSpan='2' to the ControlTemplate of the TreeViewItem as shown below.
Thats it!
Explanation:
The default ControlTemplate places the Header Content in a Grid column that does not stretch. The Grid.ColumnSpan='2' instructs the Header content to span to the rest of the Grid.
I want to add some text next to my button, but I want to use the tooltip for this text or better yet another tag I can add within the controls properties.
Then I want to reference this tag within my ControlTemplate so it will add the text next to my button, here is my button XAML:
<Button Style="{StaticResource MainMenuButton}" ToolTip="Home" Content="" />
And here is my Style:
<Style x:Key="MainMenuButton" TargetType="Button">
<Setter Property="FontFamily" Value="{StaticResource FontAwesome}" />
<Setter Property="FontSize" Value="27" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Background" Value="#545863" />
<Setter Property="Padding" Value="15" />
<Setter Property="Margin" Value="5" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid x:Name="grid">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border Grid.Column="0" x:Name="border"
CornerRadius="40"
BorderThickness="0"
Background="{TemplateBinding Background}"
Padding="{TemplateBinding Padding}"
Margin="{TemplateBinding Margin}">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"
TextElement.FontWeight="Bold" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<TextBlock Text="{Binding RelativeSource={RelativeSource Self}, Path=DataContex.ToolTip}"
FontSize="16"/>
</StackPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#757b8d" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#29a1d5" />
</Trigger>
</Style.Triggers>
</Style>
The code I have there now doesn't work: {Binding RelativeSource={RelativeSource Self}, Path=DataContex.ToolTip}.
Woopps, found the solution. Was far too simple and I expected it be more complicated.
<TextBlock Text="{TemplateBinding Tag}" FontSize="16"/>
I am overriding DataGrid row header style, and I’m been hindered with the following two issues:
1.The DataGrid row header contains an Image and a ToggleButton. When the ToggleButton is ‘Checked’ I want to change the background color of the whole row, however I only managed to change the background of the row header and couldn’t figure out a way to fire a trigger on the row level.
2.When a row is selected the row and the header background is set to different background, the other way around does not work. What I need to do is to change the background of the row when the row header is selected
Here is a the style code of the DataGridRowHeader
<Style x:Key="{x:Type DataGridRowHeader}" TargetType="{x:Type DataGridRowHeader}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridRowHeader}">
<Grid>
<Border Name="RowHeaderBorder"
BorderThickness="0,0,3,0"
Margin="0,0,0,0"
BorderBrush="{StaticResource DataGridRowBorder}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="{Binding ImageSource}" RenderOptions.BitmapScalingMode="HighQuality" Stretch="None" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<ToggleButton x:Name="tglButton" Visibility="{Binding ActiveCall}" Grid.Column="1" Content="Button" Focusable="True" BorderThickness="1" Width="80" Height="33" VerticalAlignment="Top" >
</ToggleButton>
</Grid>
</Border>
</Grid>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding ElementName=tglButton, Path=IsChecked}" Value="true">
<Setter Property="Background" TargetName="RowHeaderBorder" Value ="Green"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And here is the style of the DataGridRow:
<Style x:Key="DataGridRowStyle" TargetType="{x:Type DataGridRow}">
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="BorderBrush" Value="{StaticResource DataGridRowBorder}"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="{StaticResource DataGridRowHoveredBackground}" />
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="0" BlurRadius="20"/>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Background" Value="{StaticResource RowBackgroundSelectedBrush2}" />
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="0" BlurRadius="20"/>
</Setter.Value>
</Setter>
</Trigger>
<DataTrigger Binding="{Binding ElementName=DataGridRowHeader.tglButton, Path=IsChecked}" Value="true">
<Setter Property="Background" Value ="Green"/>
</DataTrigger>
</Style.Triggers>
</Style>
This is because tglButton is present in the row header, which is a child of the DataGridRow. A trigger defined in child row header is trying to update a property of the parent (DataGridRow) and is not able to find it.
One solution for this is to define the template for DataGridRowHeader inside the template for DataGridRow and supply a name for it, which can be used in the trigger. A very crude example:
<Style
TargetType="{x:Type DataGridRow}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridRow}">
<Border x:Name="DGR_Border"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
SnapsToDevicePixels="True"
CornerRadius="8,8,8,8">
<SelectiveScrollingGrid>
<SelectiveScrollingGrid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</SelectiveScrollingGrid.ColumnDefinitions>
<SelectiveScrollingGrid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</SelectiveScrollingGrid.RowDefinitions>
<DataGridCellsPresenter Grid.Column="1"
ItemsPanel="{TemplateBinding ItemsPanel}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
<DataGridDetailsPresenter Grid.Column="1"
Grid.Row="1"
SelectiveScrollingGrid.SelectiveScrollingOrientation="{Binding AreRowDetailsFrozen,
ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical},
Converter={x:Static DataGrid.RowDetailsScrollingConverter},
RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"
Visibility="{TemplateBinding DetailsVisibility}" />
<DataGridRowHeader Name="RHeader" Grid.RowSpan="2"
SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical"
Visibility="{Binding HeadersVisibility,
ConverterParameter={x:Static DataGridHeadersVisibility.Row},
Converter={x:Static DataGrid.HeadersVisibilityConverter},
RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ToggleButton x:Name="tglButton"
Grid.Column="1"
Content="Button"
Focusable="True"
BorderThickness="1"
Width="80"
Height="33"
VerticalAlignment="Top">
</ToggleButton>
</Grid>
</DataGridRowHeader>
</SelectiveScrollingGrid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected"
Value="True">
<Setter TargetName="DGR_Border"
Property="Background"
Value="Gray" />
</Trigger>
<DataTrigger Binding="{Binding ElementName=tglButton, Path=IsChecked}"
Value="true">
<Setter Property="Background"
TargetName="RHeader"
Value="Green" />
<Setter Property="Background"
Value="Green" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="DataContext"
Value="{Binding RelativeSource={RelativeSource Self}}" />
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="BorderBrush"
Value="Aqua" />
<Style.Triggers>
<Trigger Property="IsSelected"
Value="true">
<Setter Property="Foreground"
Value="Black" />
<Setter Property="Background"
Value="Pink" />
<Setter Property="FontWeight"
Value="Bold" />
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="0"
BlurRadius="20" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
I am trying to customize context menu in WPF, and i am able to achieve it by following this example on MSDN. The last piece in the Jigsaw is the submenu title color (Submenu header).
If you notice both submenu has white on mouse hover but Submenu title takes the normal color of the submenu items (Item 1, Item , etc) even when it is highlighted.
What do i need to do to change its highlighted or mouse hover color.
<ControlTemplate x:Key="{x:Static MenuItem.SubmenuHeaderTemplateKey}" TargetType="{x:Type MenuItem}">
<Border x:Name="Border" BorderThickness="1">
<Grid Height="22">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Icon" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Shortcut" />
<ColumnDefinition Width="13" />
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="Icon" Margin="6,0,6,0" VerticalAlignment="Center" ContentSource="Icon"/>
<ContentPresenter x:Name="HeaderHost" Margin="3,0,3,0" Grid.Column="1" VerticalAlignment="Center" ContentSource="Header" RecognizesAccessKey="True" TextOptions.TextFormattingMode="Display" />
<Path x:Name="RightArrow" Grid.Column="3" HorizontalAlignment="Center" VerticalAlignment="Center" Data="M 0 0 L 0 7 L 4 3.5 Z" Fill="#49a3e1" />
<Popup x:Name="Popup" Placement="Right" HorizontalOffset="-4" IsOpen="{TemplateBinding IsSubmenuOpen}" AllowsTransparency="True" Focusable="False" PopupAnimation="Fade">
<Border x:Name="SubmenuBorder" SnapsToDevicePixels="True" Background="White" BorderThickness="1" BorderBrush="#49a3e1">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle"/>
</Border>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Icon" Value="{x:Null}">
<Setter TargetName="Icon" Property="Visibility" Value="Collapsed" />
</Trigger>
<Trigger Property="IsHighlighted" Value="true">
<Setter Property="Background" TargetName="Border" Value="#49a3e1"/>
<Setter Property="Fill" TargetName="RightArrow" Value="White"/>
<Setter Property="Foreground" Value="White"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="false">
<Setter Property="Foreground" Value="Red"/>
</Trigger>
<Trigger SourceName="Popup" Property="AllowsTransparency" Value="True">
<Setter TargetName="SubmenuBorder" Property="Padding" Value="3" />
<Setter Property="Foreground" Value="Black"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="Pink"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>