Reputation: 312
I am having a funny issue here with WPF and a button styled. Problem is it contains a path and isMouseOver seems to only trigger when the mouse pointer is over the path but not over the button. That is I have to move the mouse pointer over the white figure inside the button to have the button shaded. Is as if the button wouldn't exist and only the path would.
This is the code for the button:
<Button Grid.Column="5" x:Name="btnClose" Width="30" Height="30" BorderBrush="White"
BorderThickness="0" Style="{StaticResource MenuButtonStyle}"
Command="{Binding ExitCommand}">
<Path Data="M0,0 L16,16 M16,0 L0,16" Stroke="White" StrokeThickness="3"
Margin="0,1,0,0" StrokeEndLineCap="Round" StrokeStartLineCap="Round" />
</Button>
And this is the style:
<Style x:Key="MenuButtonStyle" TargetType="Button">
<Setter Property="Width" Value="80" />
<Setter Property="Height" Value="80" />
<Setter Property="Margin" Value="0,0,0,0" />
<Setter Property="FontSize" Value="13.5"/>
<Setter Property="Foreground" Value="Red"/>
<Setter Property="RenderTransformOrigin" Value="0.5,0.5"/>
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="ToolTipService.ShowOnDisabled" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border CornerRadius="2.5"
x:Name="ButtonBorder"
BorderThickness="1.2"
RenderTransformOrigin="0.5,0.5">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0">
<Border x:Name="ButtonShine" Grid.Row="0" VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" >
<!--<Border.Effect>
<DropShadowEffect ShadowDepth="1" BlurRadius="1" RenderingBias="Quality" Direction="270" />
</Border.Effect>-->
</Border>
<ContentPresenter Grid.Row="0" VerticalAlignment="Center"
HorizontalAlignment="Center" />
<Border x:Name="shadowMouseOver" Grid.Row="0" Visibility="Hidden"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
Background="#7F171717">
</Border>
<Border x:Name="shadowDisabled" Grid.Row="0" Visibility="Hidden"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
Background="#AFFFFFFF">
</Border>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Button.IsEnabled" Value="false">
<Setter Property="Button.Foreground" Value="#FFDEDEDE" />
<Setter Property="Visibility" TargetName="shadowDisabled" Value="Visible"/>
</Trigger>
<Trigger Property="Button.IsMouseOver" Value="true">
<Setter Property="Visibility" TargetName="shadowMouseOver" Value="Visible"/>
</Trigger>
<Trigger Property="Button.IsPressed" Value="true">
<Setter Property="Button.RenderTransformOrigin" Value="0.5,0.5"/>
<Setter Property="Button.RenderTransform">
<Setter.Value>
<ScaleTransform ScaleX="0.95" ScaleY="0.95"/>
</Setter.Value>
</Setter>
<Setter Property="Visibility" TargetName="shadowMouseOver" Value="Visible"/>
<Setter Property="Background" TargetName="ButtonShine" >
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFBFBFBF" Offset="1"/>
<GradientStop Color="#FF383838"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" TargetName="ButtonShine" >
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFBFBFBF" Offset="1"/>
<GradientStop Color="#FF383838"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Any ideas? Bug in WPF? Something not done properly?
Upvotes: 0
Views: 157
Reputation: 10152
This is definitely not a bug, but due to the fact that you provide no background for the control in its template for the default state; thus, the hit test fails in the region outside of the path. If you notice, both shadowMouseOver
and shadowDisabled
, the only two borders that provide any background, are not visible unless the appropriate events are triggered. Thus, they are not visible to hit tests. Your path, on the other hand, is visible and so it's able to trigger events.
See Hit Testing in the Visual Layer at MSDN for more information: https://msdn.microsoft.com/library/ms752097(v=vs.100).aspx
Just in case that link fails some time in the future, here's one of the parts that pretty much summarizes what I'm trying to say here:
The purpose of the HitTest methods in the VisualTreeHelper class is to determine whether a geometry or point coordinate value is within the rendered content of a given object, such as a control or graphic element. For example, you could use hit testing to determine whether a mouse click within the bounding rectangle of an object falls within the geometry of a circle. You can also choose to override the default implementation of hit testing to perform your own custom hit test calculations. The following illustration shows the relationship between a non-rectangular object's region and its bounding rectangle.
You have a couple of options if you wish to maintain the transparent background look. Either set that background to Transparent
, due to the fact that transparent objects are visible to hits tests, or set it to some color, while turning its opacity down to 0. Best place for that background would probably be at ButtonBorder
(most outer border), but it'll be your decision to make.
Upvotes: 2