I am trying to create a context menu which allows the user to see what is under it, and so I have made the Background for both the ContextMenu, and its MenuItems Transparent. When the user moves the mouse over the MenuItems(hovers) they should show up due to a ControlTemplate Trigger on IsHighlighted. The problem is that when the mouse is over the transparent part of the MenuItems the Trigger is not working. If I change the background color of either the ContextMenu, or its MenuItems to something other than Transparent the trigger works. I thought a Transparent Background was supposed to behave like a solid color, but in this case it is not. Any ideas how to make this work?
<Window x:Class="TransparentContextMenu.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="600" Width="800">
<Window.Resources>
<ControlTemplate x:Key="contextMenuItemTemplate" TargetType="{x:Type MenuItem}">
<Grid>
<Polygon Points="0,0 180,0 180,30 0,30" Fill="Transparent" x:Name="Background"/>
<Polygon Points="0,0 180,0 180,30 0,30" Opacity="0" x:Name="HoverBorder" Fill="Gray"/>
<ContentPresenter ContentSource="Header" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted" Value="true">
<Setter Property="Opacity" Value="1" TargetName="HoverBorder"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="contextMenuStyle" TargetType="{x:Type ContextMenu}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContextMenu}">
<Border Background="Transparent">
<StackPanel IsItemsHost="True"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid Background="Transparent">
<Grid.ContextMenu>
<ContextMenu Style="{StaticResource contextMenuStyle}">
<MenuItem Header="Item A" Template="{StaticResource contextMenuItemTemplate}"/>
<MenuItem Header="Item B" Template="{StaticResource contextMenuItemTemplate}"/>
<MenuItem Header="Item C" Template="{StaticResource contextMenuItemTemplate}"/>
<MenuItem Header="Item D" Template="{StaticResource contextMenuItemTemplate}"/>
<MenuItem Header="Item E" Template="{StaticResource contextMenuItemTemplate}"/>
</ContextMenu>
</Grid.ContextMenu>
</Grid>
</Window>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
Try setting background to 'null' instead.
Related
I'm using WindowChrome class for solving problem with different icons in task bar and app header. Here is my window.style example:
<Window.Style>
<Style TargetType="{x:Type local:MainWindow}">
<Setter Property="shell:WindowChrome.WindowChrome">
<Setter.Value>
<shell:WindowChrome GlassFrameThickness="-1"
ResizeBorderThickness="4"
UseAeroCaptionButtons="True"/>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MainWindow}">
<Grid>
<!-- This is the ContentPresenter that displays the window content. -->
<Border Margin="1 30 1 1" Background="White"
>
<ContentPresenter Content="{TemplateBinding Content}" />
</Border>
<!-- Window Title -->
<Image Margin="5" VerticalAlignment="Top" HorizontalAlignment="Left" Width="16" Height="16" Source="some.ico"></Image>
<TextBlock Margin="25 5 0 0" VerticalAlignment="Top" TextAlignment="Left"
Text="{Binding RelativeSource=
{RelativeSource TemplatedParent}, Path=Title}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Style>
When not maximized - my window looks as I want.
But when maximized(by double click/maximize button click or dock to the top) the header background is black, I can't see any buttons and my icon is out of the screen bounds. :(
Any suggestions? What i'm doing wrong in my style?
In a custom control I have as the content a stackpanel (horizontal) en in it, a Textblock and a Button.
The custom control works and the result is a rectangle which is my local:DropDownToggleButton.
This reactangle is divided into two sub-rectangles: on to the left is just the <TextBlock Text="Test"part and to the right is the button <Button x:Name="ButtonTest which is stretched to fill the height of the rectangle.
However when I click in the upper-right part of the rectangle, the local:DropDownToggleButton itself receives the event and not the button that is also present there. It is as if the Button only responds to mouse events received by the Textblock in the content of the button. How can I make the whole area of the button responsive to mouse clicks?
The custom control reacts on the Clicked or PreviewMouseDown event of the button. Both events have the same problem. Also adding Panel.ZIndex="1"doesn't help.
<local:DropDownToggleButton ToolTip="Show" DropDownButton="{Binding ElementName=ButtonTest}"
VerticalAlignment="Stretch" VerticalContentAlignment="Stretch" Padding="0" BorderThickness="0"
Style="{StaticResource {x:Static ToolBar.ToggleButtonStyleKey}}">
<local:DropDownToggleButton.DropDownMenu>
<ContextMenu>
<ContextMenu.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Background="WhiteSmoke"></StackPanel>
</ItemsPanelTemplate>
</ContextMenu.ItemsPanel>
<ContextMenu.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<TextBlock Padding="6" Text="{TemplateBinding Header}" Background="{TemplateBinding Background}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Margin" Value="0"/>
<Style.Triggers>
<Trigger Property="TextBlock.IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource mouseover}"/>
</Trigger>
</Style.Triggers>
</Style>
</ContextMenu.ItemContainerStyle>
<MenuItem Header="Test 1" />
<MenuItem Header="Test 2"/>
</ContextMenu>
</local:DropDownToggleButton.DropDownMenu>
<StackPanel Orientation="Horizontal" VerticalAlignment="Stretch">
<TextBlock Text="Test" VerticalAlignment="Center"/>
<Button x:Name="ButtonTest" ToolTip="Other" Padding="0" Margin="0" VerticalContentAlignment="Stretch" VerticalAlignment="Stretch">
<Button.Template>
<ControlTemplate TargetType="Button">
<ContentPresenter/>
</ControlTemplate>
</Button.Template>
<TextBlock FontSize="16" FontFamily="Marlett" Text="6" VerticalAlignment="Center" />
</Button>
</StackPanel>
</local:DropDownToggleButton>
The reason the button does not react is because you have taken away most of what you would expect a button to have, your button template is just the ContentPresenter, so the button is literally only the textblock. Try
<ControlTemplate TargetType="Button">
<Border Background="Transparent">
<ContentPresenter/>
</Border>
</ControlTemplate>
I've got next makrup:
<Style TargetType="{x:Type MenuItem}">
<Setter Property="MinWidth" Value="65" />
<Setter Property="MinHeight" Value="30" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Border x:Name="MainBorder" BorderThickness="1" Background="Black">
<TextBlock Margin="5" Text="{TemplateBinding Header}" Foreground="{TemplateBinding Foreground}" />
<Popup x:Name="SubMenuPopup" IsOpen="{Binding Path=IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" Placement="Right"
AllowsTransparency="True" Focusable="False">
<Border Background="Gray">
<Grid x:Name="SubMenu" Grid.IsSharedSizeScope="True" Background="Transparent">
<StackPanel Margin="0" IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle" Background="Gray" />
</Grid>
</Border>
</Popup>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
When I create MenuItem somewhere and set it's Header property with "_" symbol - it doesn't create shortcut for this menu item.
Example - letter 'F' is not underlined and shortcut doesn't work.
How to support shortcuts in ControlTemplates in MenuItems?
Thanks.
It is not the complete template but instead of the TextBlock put a ContentPresenter that can recognize access keys:
<ContentPresenter Margin="5" Content="{TemplateBinding Header}" TextBlock.Foreground="{TemplateBinding Foreground}" RecognizesAccessKey="True" />
I suppose the xaml you have pasted here is only part of your implementation, so my solution is onl y a continuation of yours with the access key working...
You can find entire templates just like this one: http://msdn.microsoft.com/en-us/library/ms747082%28v=vs.85%29.aspx
If you want you menu item letter to underline itself of keypress then you have to set the InputGesture on menuitem like this:
<MenuItem Header="_File"
InputGestureText="Ctrl+F"
Commmand={Binding NewFileCommand}/>
But if you want to create shortcut for the menuitem command then you will have to create the commandbindings like below on your window:
<Window.CommandBindings>
<CommandBinding Command="local:MyCommands.NewFile" Executed="NewFile_Executed" />
</Window.CommandBindings>
<Window.InputBindings>
<KeyBinding Key="F" Modifiers="Control" Command="local:MyCommands.NewFile"/>
</Window.InputBindings>
I have the following "Style" (defined as a Resource in xaml). This is basically a "DataGridColumnHeaderStyle" with a Menu that implements Row filtering. It is assigned to the DataGrid using: ColumnHeaderStyle="{StaticResource lclDataGridColumnHeaders}"
There are times in Code Behind I need to disable the (row filtering) Menu (menuColumnOptions), which is defined in this Style. Can anyone tell me how to access this element so I can change its Visibility via C#?
I tried: myDataGrid.Template.FindName("menuColumnOptions") but I received an error, something about it must be "applied"...
(I suppose the alternative solution is to create a duplicate "Style" WITHOUT this Menu and change all the Columns to use that style...)
<Style x:Key="lclDataGridColumnHeaders" TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Foreground" Value="{StaticResource appTextColor}"/>
<Setter Property="FontWeight" Value="DemiBold"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border x:Name="BackgroundBorder"
BorderThickness="0,1,0,1"
Background="{StaticResource lclDataGridHeaderBackground}"
BorderBrush="Transparent"
Grid.ColumnSpan="2" />
<ContentPresenter Margin="6,3,6,3" VerticalAlignment="Center" />
<Path Grid.Column="1" x:Name="SortArrow" Visibility="Collapsed" Data="M0,0 L1,0 0.5,1 z"
Width="8" Height="6" Fill="Gray" Stretch="Fill" Margin="0,0,8,0"
VerticalAlignment="Center" RenderTransformOrigin="0.5,0.4" />
<Menu Grid.Column="3" x:Name="menuColumnOptions" VerticalAlignment="Center" Background="#FFF9F9F7" HorizontalAlignment="Right" >
<MenuItem Padding="0" SubmenuOpened="MenuItemColumnOptions_SubmenuOpened">
<MenuItem.Header>
<Border BorderBrush="{StaticResource appTextColor}" BorderThickness="1" CornerRadius="2" Height="20" Width="20" >
<Path Data="M0,0 L1,0 0.5,1 z" Stretch="Fill" Fill="{StaticResource appTextColor}"
Width="10" Height="8" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.4" Margin="2,0"/>
</Border>
</MenuItem.Header>
<MenuItem x:Name="clearFilterMenuItem" Header="Clear Filter..." Click="ClearFilter_Click" IsEnabled="False">
<MenuItem.Icon>
<Image Source="/IngramBook.WpfTableEditor;component/Images/edit_undohs.png" Width="16" Height="16"/>
</MenuItem.Icon>
</MenuItem>
<Separator />
<MenuItem Header="Equals..." Click="CustomAutoFilter_Click" />
<MenuItem Header="Does Not Equal..." Click="CustomAutoFilter_Click"/>
<Separator />
<MenuItem Header="Begins With..." Click="CustomAutoFilter_Click"/>
<MenuItem Header="Ends With..." Click="CustomAutoFilter_Click"/>
<Separator />
<MenuItem Header="Contains..." Click="CustomAutoFilter_Click" />
<MenuItem Header="Does Not Contain..." Click="CustomAutoFilter_Click"/>
<Separator />
<MenuItem Header="Custom Filter..." Click="CustomAutoFilter_Click">
<MenuItem.Icon>
<Image Source="/IngramBook.WpfTableEditor;component/Images/Filter2HS.png" Width="16" Height="16"/>
</MenuItem.Icon>
</MenuItem>
<Separator />
<MenuItem Header="Select Individual Values..." Click="SelectIndividualItems_Click">
<MenuItem.Icon>
<Image Source="/IngramBook.WpfTableEditor;component/Images/checkboxhs.png" Width="16" Height="16"/>
</MenuItem.Icon>
</MenuItem>
<Separator />
<MenuItem Header="Trim Trailing White Spaces..." Click="TrimTrailingWhiteSpaces_Click"/>
<MenuItem Header="Capitalization" >
<MenuItem.Icon>
<Image Source="/IngramBook.WpfTableEditor;component/Images/FontHS.png" Width="16" Height="16"/>
</MenuItem.Icon>
<MenuItem Header="Capitalize Each Word" Click="CapitalizeEachWord_Click"/>
<MenuItem Header="UPPERCASE" Click="Uppercase_Click"/>
<MenuItem Header="lowercase" Click="Lowercase_Click"/>
</MenuItem>
<Separator />
<MenuItem Header="Hide Column" Click="HideColumn_Click"/>
<Separator />
<MenuItem x:Name="deleteColumnMenuItem" Header="Delete Column" Click="dropColumnButton_Click">
<MenuItem.Icon>
<Image Source="/IngramBook.WpfTableEditor;component/Images/DeleteHS.png" Width="16" Height="16"/>
</MenuItem.Icon>
</MenuItem>
</MenuItem>
</Menu>
<Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" Style="{StaticResource ColumnHeaderGripperStyle}"/>
<Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right" Style="{StaticResource ColumnHeaderGripperStyle}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="SortDirection" Value="Ascending">
<Setter TargetName="SortArrow" Property="Visibility" Value="Visible" />
<Setter TargetName="SortArrow" Property="RenderTransform">
<Setter.Value>
<RotateTransform Angle="180" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="SortDirection" Value="Descending">
<Setter TargetName="SortArrow" Property="Visibility" Value="Visible" />
</Trigger>
<Trigger Property="SortDirection" Value="{x:Null}">
<Setter TargetName="SortArrow" Property="Visibility" Value="Collapsed" />
</Trigger>
<Trigger Property="DisplayIndex" Value="0">
<Setter Property="Visibility" Value="Collapsed" TargetName="PART_LeftHeaderGripper" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True" >
<Setter Property="Background" TargetName="BackgroundBorder" Value="{StaticResource appButtonBackgroundHighlight}" />
<Setter Property="BorderBrush" TargetName="BackgroundBorder" Value="Transparent" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
Would you be able to create an attached property (of tybe boolean or visibility) for the DataGridColumnHeader class and bind the Enabled or Visibility property of your Menu to that attached property?
http://www.deepcode.co.uk/2008/08/exposing-new-properties-for-control_15.html
Edit:
My thought is that an attached property is going to be simpler as you could just set the visibility in XAML, but I tried a quick test and I think the method you are trying to use should work just as well.
Menu myMenu = (Menu)this.myDataGrid.Template.FindName("menuColumnOptions", this.myDataGrid);
menu.Visibility = System.Windows.Visibility.Hidden;
If you're getting an error, could you show the code where you are trying to set the visibility in code behind? It sounds like you might be trying to access the DataGridColumnHeader's Template before it's been fully constructed (in which case moving your code to the Loaded event might solve your problem).
Edit 2:
<Window x:Class="TestApp11.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:l="clr-namespace:TestApp11"
xmlns:s="clr-namespace:System;assembly=mscorlib"
Title="Window1" Height="500" Width="800">
<Grid>
<Grid.Resources>
<Style x:Key="MyButtonStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderBrush="Red" BorderThickness="2">
<StackPanel>
<TextBlock x:Name="MyTextBlock" Text="Control Template's TextBlock 1" />
<ContentPresenter />
<TextBlock Text="Control Template's TextBlock 2" />
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button x:Name="scottsButton" Style="{StaticResource MyButtonStyle}">
<TextBlock Text="This Text should appear where the Control Template's ContentPresenter is located."/>
</Button>
<Button Grid.Row="1" Content="Click to hide visibility of TextBlock1" Click="Button_Click" />
</Grid>
</Window>
Code Behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
TextBlock tb = (TextBlock)this.scottsButton.Template.FindName("MyTextBlock", this.scottsButton);
tb.Visibility = System.Windows.Visibility.Hidden;
}
}
Here is what I ended up doing.
I copied the Style and removed the Menu from this Copy.
Then, in code I just set it using:
myDataGrid.ColumnHeaderStyle = (Style)FindResource("lclDataGridLockedColumnHeaders");
I create popup menu like this.
<DockPanel.ContextMenu>
<ContextMenu Background="#CD252220" Opacity="0.95" Foreground="LightGray" BorderBrush="DarkGray">
<MenuItem Header="_Save Image..." x:Name="btSave" IsEnabled="False" Click="btSave_Click" Style="{StaticResource MyStyle}">
<MenuItem.Icon>
<Image Source="icons/save.png" Width="16" Height="16" Style="{StaticResource IconStyle}"/>
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</DockPanel.ContextMenu>
Why left-side of this menu is WHITE????? It'll be a #CD252220 color or transparent, bun not white!!!!!!
How to fix it? :)
http://itrash.ru/idb/40e872e71346dcf9bd58ba8aec0b2a17/omenu.png.html - menu screenshot
P.S. In XP it's OK. Menu is White only on Vista (don't have W7)
I find solution! You have to just set property OverridesDefaultStyle in Style-defenition section ;)
<Style x:Key="{x:Type ContextMenu}" 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 Background="#CD222120" CornerRadius="7, 7, 8, 8" BorderBrush="DarkGray" BorderThickness="2" Opacity="0.96">
<StackPanel ClipToBounds="True" Orientation="Vertical" IsItemsHost="True" Margin="5,4,5,4"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="{x:Static MenuItem.TopLevelItemTemplateKey}" TargetType="{x:Type MenuItem}">
<Border Name="Border" >
<Grid>
<ContentPresenter Margin="6,3,6,3" ContentSource="Header" RecognizesAccessKey="True" />
</Grid>
</Border>
</ControlTemplate>
If you will declare a custom style for your context menu, This way it will be same for all OS.