What I'm Trying to Achieve
For simplicity, I have a grid of cells and I'm trying to add the FocusVisualStyle dashed rectangle to each cell when it is focused. However the style only works when the element is navigated to using the keyboard, per its design. I'm looking to achieve the same effect, but have it work with Keyboard focus and Mouse focus (when the cell is clicked).
What I Have Tried
I looked into using containers like a Border
, but that doesn't have dashed lines, attempted to use a dashed rectangle and position it over the element, but that was providing inconsistent results. I also tried to attach a trigger to the IsFocused
property of the cell, but that only works for Keyboard Focus.
Current Code
Right now I have events set to the cell (a StackPanel
) that allow for my custom navigation through the grid. My current "Visual Style" is to change the background to a color, which works for both Mouse and Keyboard Focus. I'm looking to swap out the background change for a dashed rectangle around the cell, however the XAML I tried doesn't work since FocusVisualStyle only works with keyboard focus.
Here is a simplified version of my XAML and C# of what I have tried
XAML
<!-- The "cell" I'm trying to acheive a dashed border around -->
<StackPanel x:Key="ContactCell"
Focusable="True"
GotFocus="StackPanel_GotFocus"
LostFocus="StackPanel_LostFocus"
PreviewMouseDown="Contact_Select"
Style="{DynamicResource ContactFocusStyle}">
<!-- other children in here -->
</StackPanel>
<Style x:Key="ContactFocusStyle" TargetType="StackPanel">
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="FocusVisualStyle"
Value="{DynamicResource MyFocusVisualStyle}"/>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="MyFocusVisualStyle">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Stroke="Black"
StrokeDashArray="2 3"
Fill="Transparent"
StrokeDashCap="Round"
RadiusX="3"
RadiusY="3"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
C#
private void Contact_Select(object send, MouseButtonEventArgs e)
{
StackPanel sender = (StackPanel)send;
sender.Focus();
}
private void StackPanel_GotFocus(object sender, RoutedEventArgs e)
{
StackPanel s = (StackPanel)sender;
s.Background = Brushes.Red;
}
private void StackPanel_LostFocus(object sender, RoutedEventArgs e)
{
StackPanel s = (StackPanel)sender;
s.Background = Brushes.Transparent;
}