Path overriding controls beneath - c#

Related to the accepted answer here
I have a set of check boxes in a grid, these check boxes are style to look like the parts of a shoe. (heel, edge, instep etc)
The user needs to be able to click the Edge (1 check box) and each of the other "Regions" seperately
Using the fabulous answer in the linked question I have got something that looks good.
However I am not able to select the edge. I can select each of the individual regions, but these are over the top of the edge meaning that they are selected before the mouse event can get to the edge path.
I have tried setting the Panel.ZIndex of the edge path and this enables me to select the edge, however this now stops me from selecting the individual regions.
ZIndex = 0:
ZIndex = 99:
Can someone point me to a solution?
<Grid Width="100" Height="200">
<Grid.RowDefinitions>
<RowDefinition Height="2*" />
<RowDefinition Height="4*" />
<RowDefinition Height="2*" />
<RowDefinition Height="2*" />
<RowDefinition Height="2*" />
</Grid.RowDefinitions>
<Grid.Resources>
<PathGeometry x:Key="DynamicClipGeometry" Figures="{StaticResource ShoeEdgeFigures}">
<PathGeometry.Transform>
<MultiBinding>
<MultiBinding.Converter>
<converters:SizeToScaleConverter />
</MultiBinding.Converter>
<Binding Path="ActualWidth" RelativeSource="{RelativeSource AncestorType=Grid}" />
<Binding Path="ActualHeight" RelativeSource="{RelativeSource AncestorType=Grid}" />
</MultiBinding>
</PathGeometry.Transform>
</PathGeometry>
</Grid.Resources>
<Grid.Clip>
<StaticResource ResourceKey="DynamicClipGeometry" />
</Grid.Clip>
<!-- The edge check box -->
<CheckBox x:Name="ShoeEdgeRegion"
Grid.Row="0"
Grid.RowSpan="5">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Border Background="Transparent" BorderThickness="0">
<Path x:Name="MainPath"
Data="{StaticResource ShoeEdgeGeometry}"
Fill="Transparent"
IsHitTestVisible="False"
Stretch="Fill"
Stroke="Black"
StrokeThickness="-10" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="MainPath" Property="Stroke" Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="MainPath" Property="Stroke" Value="{StaticResource RedBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</CheckBox.Style>
</CheckBox>
<!-- The Toe check box -->
<CheckBox x:Name="ShoeToeRegion" Grid.Row="0">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid>
<Rectangle x:Name="MainPath"
Fill="{StaticResource TransparentBrush}"
Stroke="Black"
StrokeThickness="1" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="MainPath" Property="Stroke" Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="MainPath" Property="Stroke" Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="MainPath" Property="Fill" Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="MainPath" Property="Fill" Value="{StaticResource RedBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</CheckBox.Style>
</CheckBox>
<!-- The Sole check box -->
<CheckBox x:Name="ShoeSoleRegion"
Grid.Row="1"
Margin="0,-1,0,0">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid>
<Rectangle x:Name="MainPath"
Fill="{StaticResource TransparentBrush}"
Stroke="Black"
StrokeThickness="1" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="MainPath" Property="Stroke" Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="MainPath" Property="Stroke" Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="MainPath" Property="Fill" Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="MainPath" Property="Fill" Value="{StaticResource RedBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</CheckBox.Style>
</CheckBox>
<!-- The Instep check box -->
<CheckBox x:Name="ShoeInstepRegion"
Grid.Row="2"
Margin="0,-1,0,0">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid>
<Rectangle x:Name="MainPath"
Fill="{StaticResource TransparentBrush}"
Stroke="Black"
StrokeThickness="1" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="MainPath" Property="Stroke" Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="MainPath" Property="Stroke" Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="MainPath" Property="Fill" Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="MainPath" Property="Fill" Value="{StaticResource RedBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</CheckBox.Style>
</CheckBox>
<!-- The Lower heel check box -->
<CheckBox x:Name="ShoeLowerHeelRegion"
Grid.Row="3"
Margin="0,-1,0,0">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid>
<Rectangle x:Name="MainPath"
Fill="{StaticResource TransparentBrush}"
Stroke="Black"
StrokeThickness="1" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="MainPath" Property="Stroke" Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="MainPath" Property="Stroke" Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="MainPath" Property="Fill" Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="MainPath" Property="Fill" Value="{StaticResource RedBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</CheckBox.Style>
</CheckBox>
<!-- The heel check box -->
<CheckBox x:Name="ShoeHeelRegion"
Grid.Row="4"
Margin="0,-1,0,0">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid>
<Rectangle x:Name="MainPath"
Fill="{StaticResource TransparentBrush}"
Stroke="Black"
StrokeThickness="1" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="MainPath" Property="Stroke" Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="MainPath" Property="Stroke" Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="MainPath" Property="Fill" Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="MainPath" Property="Fill" Value="{StaticResource RedBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</CheckBox.Style>
</CheckBox>
</Grid>

The solution with setting Panel.ZIndex is a good one.
The key to success here is the crucial difference between a Transparent brush and a null brush (i.e. no brush at all).
In terms of visual features they are the same - Transparent brush is lookless, so we don't see any difference. But in terms of mouse input it is solid, which means it takes part in hit-testing, whereas when there's no brush, there's nothing to hit-test.
To put it in simple words - Transparent brush is invisible to human eye, but is visible to the mouse.
So what you're after is a path with hit-test visible stroke and no fill (as opposed to transparent fill). To achieve that you should modify your path with IsHitTestVisible="True" and Fill="{x:Null}". Also, you need to set the background of the Border in your template to null, or drop it altogether, because it wouldn't serve any purpose anyway.
Here's how your edge CheckBox template should look like:
<CheckBox x:Name="ShoeEdgeRegion" Grid.Row="0" Grid.RowSpan="5" Panel.ZIndex="1">
<CheckBox.Style>
<Style TargetType="CheckBox">
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Path x:Name="MainPath"
Data="{StaticResource ShoeEdgeGeometry}"
IsHitTestVisible="True"
Fill="{x:Null}"
Stretch="Fill"
Stroke="Black"
StrokeThickness="-10" />
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="MainPath"
Property="Stroke"
Value="{StaticResource RedBrush}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="MainPath"
Property="Stroke"
Value="{StaticResource RedBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</CheckBox.Style>
</CheckBox>
You could also omit setting Path.IsHitTestVisible and Path.Fill properties since those are default values for these properties.

Related

Change Path Fill inside radio button WPF C#

I read on internet that to make a custom style of radio button you need to create a toggle button style.
So here my style :
<Style TargetType="{x:Type ToggleButton}">
<Setter Property="Background" Value="{StaticResource MainOrangeBrush}" />
<Setter Property="Foreground" Value="{StaticResource MainDarkerGrayBrush}" />
<Setter Property="BorderBrush" Value="{StaticResource MainDarkerGrayBrush}" />
<Setter Property="Focusable" Value="False" />
<Setter Property="Margin" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="{StaticResource MainDarkerGrayBrush}" />
<Setter Property="Background" Value="{StaticResource MainWhiteBrush}" />
<Setter Property="BorderBrush" Value="{StaticResource MainOrangeBrush}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Foreground" Value="{StaticResource MainOrangeBrush}" />
<Setter Property="Background" Value="{StaticResource MainWhiteBrush}" />
<Setter Property="BorderBrush" Value="{StaticResource MainDarkerGrayBrush}" />
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Foreground" Value="{StaticResource MainOrangeBrush}" />
<Setter Property="Background" Value="{StaticResource MainWhiteBrush}" />
<Setter Property="BorderBrush" Value="{StaticResource MainOrangeBrush}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="{StaticResource MainDarkerGrayBrush}" />
<Setter Property="Background" Value="{StaticResource DisableGrayBrush}" />
<Setter Property="BorderBrush" Value="{StaticResource MainWhiteBrush}" />
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type RadioButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ToggleButton Content="{Binding Path=(Content), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type RadioButton}}}" IsChecked="{Binding Path=(IsChecked), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type RadioButton}}}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
I still don't fully understand ContentTemplate and ContentPresenter. I understand that the content presenter is for everything inside the UI element.
So my problem is that I want to set the fill the same color as the foreground inside the toggle button:
<RadioButton
x:Name="Btn"
Width="40"
Height="40"
HorizontalAlignment="Right"
IsChecked="{Binding IsChecked}"
ToolTip="Btn">
<Path
Width="30"
Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="F1 M 19.135,13.006 L 12.740,13.006 L 17.243,0.000 L 0.000,17.142 L 6.397,17.142 L 1.480,30.148 L 19.135,13.006 Z"
Fill="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type ToggleButton}}}"
Stretch="Uniform" />
</RadioButton>
This line does not work :
Fill="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type ToggleButton}}}"
Can you help?
I read on internet that to make a custom style of radio button you need to create a toggle button style.
No. You have to create a style for the type RadioButton. The RelativeSource binding does not work, because it does not search for ancestors within the control template and will therefore not find the ToggleButton.
In order to solve your issue, you should create an appropriate style for RadioButton. It is not necessary to use a toggle button in it, but even if you would, the triggers would be defined in the control template, too. Moreover, the style for the ToggleButton as you have defined it is implicit (without an x:Key), which causes it to be applied to every toggle button in scope, not just the RadioButton and that is not what you want.
I have created a sample style that might look similar to what your are trying to do.
<Style x:Key="FocusVisual1">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" StrokeDashArray="1 2" SnapsToDevicePixels="true" StrokeThickness="1" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="OptionMarkFocusVisual1">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="14,0,0,0" StrokeDashArray="1 2" SnapsToDevicePixels="true" StrokeThickness="1" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type RadioButton}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual1}"/>
<Setter Property="Background" Value="{StaticResource MainOrangeBrush}" />
<Setter Property="Foreground" Value="{StaticResource MainDarkerGrayBrush}" />
<Setter Property="BorderBrush" Value="{StaticResource MainDarkerGrayBrush}" />
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Focusable" Value="False" />
<Setter Property="Margin" Value="0" />
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<Grid x:Name="templateRoot" Background="Transparent" SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border x:Name="radioButtonBorder" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="1,1,2,1" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<Grid x:Name="markGrid" Margin="2">
<Path x:Name="optionMark"
MinHeight="6"
MinWidth="6"
Margin="2"
Opacity="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="F1 M 19.135,13.006 L 12.740,13.006 L 17.243,0.000 L 0.000,17.142 L 6.397,17.142 L 1.480,30.148 L 19.135,13.006 Z"
Fill="{TemplateBinding Foreground}"
Stretch="Uniform" />
</Grid>
</Border>
<ContentPresenter x:Name="contentPresenter" Grid.Column="1" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasContent" Value="true">
<Setter Property="FocusVisualStyle" Value="{StaticResource OptionMarkFocusVisual1}"/>
<Setter Property="Padding" Value="4,-1,0,0"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="radioButtonBorder" Value="{StaticResource MainWhiteBrush}"/>
<Setter Property="BorderBrush" TargetName="radioButtonBorder" Value="{StaticResource MainOrangeBrush}"/>
<Setter Property="Fill" TargetName="optionMark" Value="{StaticResource MainDarkerGrayBrush}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="radioButtonBorder" Value="{StaticResource DisableGrayBrush}"/>
<Setter Property="BorderBrush" TargetName="radioButtonBorder" Value="{StaticResource MainWhiteBrush}"/>
<Setter Property="Fill" TargetName="optionMark" Value="{StaticResource MainDarkerGrayBrush}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" TargetName="radioButtonBorder" Value="{StaticResource MainWhiteBrush}"/>
<Setter Property="BorderBrush" TargetName="radioButtonBorder" Value="{StaticResource MainDarkerGrayBrush}"/>
<Setter Property="Fill" TargetName="optionMark" Value="{StaticResource MainOrangeBrush}"/>
</Trigger>
<Trigger Property="IsChecked" Value="true">
<Setter Property="Opacity" TargetName="optionMark" Value="1"/>
</Trigger>
<Trigger Property="IsChecked" Value="{x:Null}">
<Setter Property="Opacity" TargetName="optionMark" Value="0.56"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The result looks like below. It is still a radio button, but with your custom Path as option mark and your custom colors applied to the respective states.
In this example, the Path is embedded in the control template and the Content, here the text Test is still applied. You can of course further customize the template so that it fits your requirements.
If you want the Content and the option mark to be customizable without creating a different style, you will have to create a custom radio button control derived from RadioButton and expose a dependency property to specify the option mark content. Then you can bind it in the control template, but that is another question.

Style Basedon not working with checkbox

I have a style defined in a resource dictionary to make my checkbox look like a button:
<Style TargetType="CheckBox" x:Key="CBCheckBoxButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Border Name="BackgroundBorder" Background="Black" CornerRadius="20">
<Grid>
<Rectangle x:Name="UpperRect" Margin="1" Grid.Row="0" RadiusX="20" RadiusY="20" Fill="{StaticResource GrayGradient}"/>
<TextBlock Name="ButtonContent" Text="{TemplateBinding Content}" Margin="3" VerticalAlignment="Center" TextAlignment="Center" TextWrapping="Wrap" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="UpperRect" Property="Fill" Value="{StaticResource LightBlueGradient}" />
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="UpperRect" Property="Fill" Value="{StaticResource BlueGradient}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="BackgroundBorder" Property="Background" Value="DarkGray"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Effect" Value="{StaticResource ShadowEffect}" />
<Setter Property="FontSize" Value="14"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="FontFamily" Value="Calibri"/>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="DarkGray"/>
<Setter Property="Effect" Value="{StaticResource DisableShadowEffect}" />
</Trigger>
</Style.Triggers>
</Style>
When used like so it works great:
<CheckBox Width="80" Height="80" Margin="10" Content="{Binding Y2LockAxisString}" Command="{Binding Y2LockDisableEnableCommand}" Style="{StaticResource CBCheckBoxButton}"/>
But I need to add a style so that different commands etc. are called depending on the state of the check box. So I used the basedon property:
<CheckBox Width="80" Height="80" Margin="10">
<Style TargetType="{x:Type CheckBox}" BasedOn="{StaticResource CBCheckBoxButton}">
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Command" Value="{Binding ExecuteX2LockDisable}" />
</Trigger>
<Trigger Property="IsChecked" Value="False">
<Setter Property="Command" Value="{Binding ExecuteX2LockEnable}" />
</Trigger>
</Style.Triggers>
</Style>
</CheckBox>
But the checkbox looks like a default checkbox with none of the appearance elements applied to it.
Why isn't the appearance style working?
It seems you are adding the Style as Content, instead of Style.
Have you tried
<CheckBox Width="80" Height="80" Margin="10">
<CheckBox.Style>
<Style --- snip --->
</Style>
</CheckBox.Style>
</CheckBox>

Clicking on subitem in context menu triggers both subitem and item click event

I'm trying to create a template for my menuItem which is the following (from MSDN) :
<Style x:Key="StyleContext" TargetType="ContextMenu">
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Grid.IsSharedSizeScope" Value="true"/>
<Setter Property="HasDropShadow" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContextMenu">
<Border
Name="Border"
Background="{StaticResource CouleurFond}"
BorderBrush="{StaticResource CouleurBouton}"
BorderThickness="2"
Width="Auto" >
<StackPanel IsItemsHost="True"
KeyboardNavigation.DirectionalNavigation="Cycle"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="HasDropShadow" Value="true">
<Setter TargetName="Border" Property="Padding" Value="0,3,0,3"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="{x:Static MenuItem.SeparatorStyleKey}"
TargetType="Separator">
<Setter Property="Height" Value="1"/>
<Setter Property="Margin" Value="0,4,0,4"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Separator">
<Border BorderBrush="{StaticResource CouleurSecondaire}"
BorderThickness="1"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- TopLevelHeader -->
<ControlTemplate x:Key="{x:Static MenuItem.TopLevelHeaderTemplateKey}"
TargetType="MenuItem">
<Border Name="Border" Cursor="Hand">
<Grid>
<ContentPresenter
Margin="6,3,6,3"
ContentSource="Header"
RecognizesAccessKey="True" />
<Popup
Name="Popup"
Placement="Bottom"
IsOpen="{TemplateBinding IsSubmenuOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Fade">
<Border
Name="SubmenuBorder"
SnapsToDevicePixels="True"
Background="{StaticResource CouleurFond}"
BorderBrush="{StaticResource CouleurBouton}"
BorderThickness="2" >
<StackPanel
IsItemsHost="True"
KeyboardNavigation.DirectionalNavigation="Cycle" />
</Border>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSuspendingPopupAnimation" Value="true">
<Setter TargetName="Popup" Property="PopupAnimation" Value="None"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="true">
<Setter TargetName="Border" Property="Background"
Value="{StaticResource CouleurBoutonHover}"/>
<Setter TargetName="Border" Property="BorderBrush"
Value="Transparent"/>
<Setter Property="Foreground" Value="{StaticResource CouleurTexteBoutonHover}"/>
</Trigger>
<Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="True">
<Setter TargetName="SubmenuBorder" Property="Padding" Value="0,0,0,3"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!-- TopLevelItem -->
<ControlTemplate
x:Key="{x:Static MenuItem.TopLevelItemTemplateKey}"
TargetType="MenuItem">
<Border Name="Border" Cursor="Hand" >
<Grid>
<ContentPresenter
Margin="6,3,6,3"
ContentSource="Header"
TextBlock.FontFamily="Helvetica"
TextBlock.Foreground="{TemplateBinding Foreground}"
RecognizesAccessKey="True" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsHighlighted" Value="true">
<Setter TargetName="Border" Property="Background"
Value="{StaticResource CouleurBoutonHover}"/>
<Setter TargetName="Border" Property="BorderBrush" Value="Transparent"/>
<Setter Property="Foreground"
Value="{StaticResource CouleurTexteBoutonHover}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground"
Value="{StaticResource CouleurTexteBoutonDisabled}"/>
<Setter TargetName="Border" Property="Background" Value="{StaticResource CouleurBoutonDisabled}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!-- SubmenuItem
-->
<ControlTemplate
x:Key="{x:Static MenuItem.SubmenuItemTemplateKey}"
TargetType="MenuItem"
>
<Border
Name="Border"
BorderBrush="{StaticResource CouleurBouton}"
Background="{StaticResource CouleurFond}"
BorderThickness="0" Cursor="Hand">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Icon"/>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Shortcut"/>
<ColumnDefinition Width="13"/>
</Grid.ColumnDefinitions>
<ContentPresenter
Name="Icon"
Margin="6,0,6,0"
VerticalAlignment="Center"
ContentSource="Icon"/>
<Border
Name="Check"
Width="13" Height="13"
Visibility="Collapsed"
Margin="6,0,6,0"
Background="{StaticResource CouleurFond}"
BorderThickness="2"
BorderBrush="{StaticResource CouleurBouton}">
<Path
Name="CheckMark"
Width="7" Height="7"
Visibility="Hidden"
SnapsToDevicePixels="False"
Stroke="{StaticResource CouleurSecondaire}"
StrokeThickness="2"
Data="M 0 0 L 7 7 M 0 7 L 7 0" />
</Border>
<ContentPresenter
Name="HeaderHost"
Grid.Column="1"
ContentSource="Header"
RecognizesAccessKey="True"/>
<TextBlock x:Name="InputGestureText"
Grid.Column="2"
Foreground="{StaticResource CouleurTexte}"
Text="{TemplateBinding InputGestureText}"
Margin="5,2,0,2"
DockPanel.Dock="Right" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Icon" Value="{x:Null}">
<Setter TargetName="Icon" Property="Visibility" Value="Hidden"/>
</Trigger>
<Trigger Property="IsChecked" Value="true">
<Setter TargetName="CheckMark" Property="Visibility" Value="Visible"/>
</Trigger>
<Trigger Property="IsCheckable" Value="true">
<Setter TargetName="Check" Property="Visibility" Value="Visible"/>
<Setter TargetName="Icon" Property="Visibility" Value="Hidden"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="true">
<Setter TargetName="Border" Property="Background"
Value="{StaticResource CouleurBoutonHover}"/>
<Setter TargetName="InputGestureText" Property="Foreground"
Value="{StaticResource CouleurTexteBoutonHover}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="InputGestureText" Property="Foreground" Value="{StaticResource CouleurTexteBoutonDisabled}"/>
<Setter TargetName="Border" Property="Background" Value="{StaticResource CouleurBoutonDisabled}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!-- SubmenuHeader -->
<ControlTemplate
x:Key="{x:Static MenuItem.SubmenuHeaderTemplateKey}"
TargetType="MenuItem">
<Border Name="Border"
BorderBrush="{StaticResource CouleurBouton}"
Background="{StaticResource CouleurFond}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Icon"/>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Shortcut"/>
<ColumnDefinition Width="13"/>
</Grid.ColumnDefinitions>
<ContentPresenter
Name="Icon"
Margin="6,0,6,0"
VerticalAlignment="Center"
ContentSource="Icon"/>
<ContentPresenter
Name="HeaderHost"
Grid.Column="1"
ContentSource="Header"
RecognizesAccessKey="True"/>
<TextBlock x:Name="InputGestureText"
Grid.Column="2"
Text="{TemplateBinding InputGestureText}"
Foreground="{StaticResource CouleurTexte}"
Margin="5,2,2,2"
DockPanel.Dock="Right"/>
<Path
Grid.Column="3"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 0 L 0 7 L 4 3.5 Z"
Fill="{StaticResource CouleurSecondaire}" />
<Popup
Name="Popup"
Placement="Right"
HorizontalOffset="3"
IsOpen="{TemplateBinding IsSubmenuOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Fade">
<Border
Name="SubmenuBorder"
SnapsToDevicePixels="True"
Background="{StaticResource CouleurFond}"
BorderBrush="{StaticResource CouleurBouton}"
BorderThickness="1" >
<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 TargetName="Border" Property="Background"
Value="{StaticResource CouleurBoutonHover}"/>
<Setter TargetName="InputGestureText" Property="Foreground" Value="{StaticResource CouleurTexteBoutonHover}"/>
</Trigger>
<Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="True">
<Setter TargetName="SubmenuBorder" Property="CornerRadius" Value="0"/>
<Setter TargetName="SubmenuBorder" Property="Padding" Value="0,3,0,3"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="InputGestureText" Property="Foreground" Value="{StaticResource CouleurTexteBoutonDisabled}"/>
<Setter TargetName="Border" Property="Background" Value="{StaticResource CouleurBoutonDisabled}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!-- MenuItem Style -->
<Style x:Key="MenuItemStyle" TargetType="MenuItem">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Opacity" Value="0.95" />
<Style.Triggers>
<Trigger Property="Role" Value="TopLevelHeader">
<Setter Property="Template"
Value="{StaticResource {x:Static MenuItem.TopLevelHeaderTemplateKey}}"/>
<Setter Property="Grid.IsSharedSizeScope" Value="true"/>
</Trigger>
<Trigger Property="Role" Value="TopLevelItem">
<Setter Property="Template"
Value="{StaticResource {x:Static MenuItem.TopLevelItemTemplateKey}}"/>
</Trigger>
<Trigger Property="Role" Value="SubmenuHeader">
<Setter Property="Template"
Value="{StaticResource {x:Static MenuItem.SubmenuHeaderTemplateKey}}"/>
</Trigger>
<Trigger Property="Role" Value="SubmenuItem">
<Setter Property="Template"
Value="{StaticResource {x:Static MenuItem.SubmenuItemTemplateKey}}"/>
</Trigger>
</Style.Triggers>
</Style>
<!-- Design des contextmenu-->
And in my code :
MenuItem mySubItem = new MenuItem() { Header = "SubItem" };
mySubItem .Style = (Style)this.FindResource("MenuItemStyle");
mySubItem.Click += mySubItem _Click;
MenuItem m2 = new MenuItem();
m2.Header = LibLOCA.Localisation.GetStringFromResources("OPTION_MENU");
m2.Style = (Style)this.FindResource("MenuItemStyle");
m2.Click += m2_Click;
m2.Items.Add(mySubItem );
contextMenu.Items.Add(m2);
The ContextMenu looks OK, and I can click on both menuItems, but if I click on the subItem :
The application will call "mySubItem_click" and then it will also call "m2_click".
Why is "m2_click" called even though I didn't click on the menu Item associated with it ?
Is there a problem with my template or with my code ?
Thank you :)
You have to handle the subitem so that it doesn't bubble up the event to the Parent menu item.
On the click event handler
The RoutedEventArgs has a property called Handled set it to true

How To Style Button's Hover And Click Foreground?

I am new to Styles and not sure on the best way to create a Button style to change the Foreground of IsMouseOver and IsPressed. I used a Border for a template because it has a CornerRadius and background and border properties. But Border does not have a Foreground property. Using Button as the template doesn't work well since the default look isn't being overridden.
What is a better way to style a Button template with Foreground behavior? Maybe using a label inside the border?
Here is the App.xaml:
<Application.Resources>
<Style TargetType="Button" x:Key="MyButton">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="MinHeight" Value="34"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="shortcutbutton"
BorderThickness="1"
BorderBrush="Black"
Background="Gray">
<ContentPresenter Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="shortcutbutton" Property="Background" Value="#FFDADADA" />
<Setter TargetName="shortcutbutton" Property="BorderBrush" Value="#EEEEEE" />
<!--<Setter TargetName="Border" Property="Foreground" Value="Black" />-->
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="shortcutbutton" Property="Background" Value="DarkGray" />
<Setter TargetName="shortcutbutton" Property="BorderBrush" Value="Black" />
<!--<Setter TargetName="Border" Property="Foreground" Value="Red" />-->
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
And the xaml:
<StackPanel HorizontalAlignment="Center" Height="100" VerticalAlignment="Center" Width="100">
<Button Content="Button" Height="41" Style="{DynamicResource MyButton}"/>
</StackPanel>
You need to move your Triggers from the ControlTemplate to the Style. Something like this:
<Style TargetType="Button">
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="MinHeight" Value="34"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="shortcutbutton"
BorderThickness="1"
BorderBrush="Black"
Background="Gray">
<ContentPresenter Margin="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Foreground" Value="#FFDADADA" />
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Foreground" Value="DarkGray" />
</Trigger>
</Style.Triggers>
</Style>
What you can do is set attached property of TextElement on the Border and like that every text element within your Border will be of that colour:
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="shortcutbutton" Property="Background" Value="#FFDADADA" />
<Setter TargetName="shortcutbutton" Property="BorderBrush" Value="#EEEEEE" />
<Setter TargetName="shortcutbutton" Property="TextElement.Foreground" Value="White"/>
</Trigger>
...
</ControlTemplate.Triggers>

Change rectangle Background when selecting a pressing a Button

Basically this is a button existing out of rectangle and several textblocks. The rectangle Fill is representing the background of my button. How can i change this when the button is pressed?
The background also has to stay in that color after pressing the button. This basically shows the user visually what buttons have been pressed and what not.
Part of my Style:
<Style x:Key="ButtonStyleReg" TargetType="{x:Type myClasses:RegButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid x:Name="regButton">
<Rectangle Name="rectangleBtn" Fill="#FF89959A" Height="Auto" RadiusY="15" RadiusX="15" Stroke="White" Width="Auto"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True"/>
<Trigger Property="IsDefaulted" Value="True"/>
<Trigger Property="IsPressed" Value="True" >
<Setter TargetName="rectangleBtn" Property="Fill" Value="Blue" />
</Trigger>
<Trigger Property="IsEnabled" Value="False"/>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="FontSize" Value="10.667"/>
You must address the correct element, try giving the rectangle a name and pointing the setter to it by name reference:
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid x:Name="regButton">
<Rectangle Fill="#FF89959A"
x:Name="rect"
Height="Auto"
RadiusY="15"
RadiusX="15"
Stroke="White"
Width="Auto" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused"
Value="True" />
<Trigger Property="IsDefaulted"
Value="True" />
<Trigger Property="IsPressed"
Value="True">
<Setter Property="Background"
TargetName="rect"
Value="Blue" />
<!--??-->
</Trigger>
<Trigger Property="IsEnabled"
Value="False" />
</ControlTemplate.Triggers>
</ControlTemplate>

Categories