Это (зашифрованный) отрывок из MSDN говорит о более общей форме этого вопроса:
Фокуса визуальных стилей действуют исключительно для фокус клавиатуры. Таким образом, фокус визуальных стилей является типом функции доступности. Если вы хотите, чтобы изменения пользовательского интерфейса для любого типа фокуса, будь то с помощью мыши, клавиатуры или программно, тогда вы не должны использовать фокусные визуальные стили и вместо этого должны использовать сеттеры и триггеры в стилях или шаблонах, которые работают со значением общих свойств фокусировки таких как IsFocused или IsFocusWithin.
Сегодня последний бит об использовании триггеров, вероятно, будет лучше заменен предложением о том, что вы используете диспетчер визуальных состояний. Вот некоторые XAML, которые делают это таким образом, но также сохраняет исходную настройку Button
's FocusVisualStyle
. Эта настройка рисует пунктирный прямоугольник двумя пикселями внутри Button
, когда он получает фокус с клавиатуры. Мои Storyboard
s для Focused
и Unfocused
визуальных состояний добавляют и удаляют сплошной прямоугольник, четыре пикселя внутри Button
, всякий раз, когда он получает или теряет фокус по любой причине.
Если создать пару Button
с в WPF окна и манипулировать фокус с помощью клавиатуры и мыши, нажав эти Button
S с пробела и мыши, вы увидите, что Button
часто имеет фокус, когда FocusVisualStyle
не отображается. Опять же, это (в соответствии с выдержкой выше) по дизайну. (Я озадачен тем, как это «функция доступности», так как это может легко игнорировать, чтобы показать, какой элемент управления будет нажат при следующем нажатии на клавишу пробела. Моя склонность просто не использовать его вообще.)
ПРИМЕЧАНИЕ. Код ниже предназначен для пользовательского элемента управления, полученного из Button
, называемого «XLButton
». Вы можете изменить Style
TargetType
на Button
, если вы не хотите создавать настраиваемый элемент управления, чтобы попробовать это.
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ExLuminaControls">
<Style x:Key="FocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2"
SnapsToDevicePixels="true"
Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"
StrokeThickness="1"
StrokeDashArray="1 2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
<Style TargetType="{x:Type local:XLButton}">
<Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
<Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="{x:Null}"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:XLButton}">
<Grid>
<Border x:Name="border"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
SnapsToDevicePixels="true"/>
<Rectangle x:Name ="glow" Fill="White" Opacity="0"/>
<Rectangle x:Name="shade" Fill="Black" Opacity="0"/>
<ContentPresenter x:Name="contentPresenter"
Focusable="False"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Rectangle x:Name="dis" Fill="Gray" Opacity="0"/>
<Rectangle x:Name="foc" Margin="4" SnapsToDevicePixels="true"
Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"
StrokeThickness="1" Opacity="0"/>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup Name="CommonStates">
<VisualState Name="Normal">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="glow"
Storyboard.TargetProperty="Opacity"
To="0" Duration="0:0:.1"/>
</Storyboard>
</VisualState>
<VisualState Name="MouseOver">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="glow"
Storyboard.TargetProperty="Opacity"
To=".25" Duration="0:0:.1"/>
</Storyboard>
</VisualState>
<VisualState Name="Pressed">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="shade"
Storyboard.TargetProperty="Opacity"
To=".25" Duration="0:0:0"/>
</Storyboard>
</VisualState>
<VisualState Name="Disabled">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="dis"
Storyboard.TargetProperty="Opacity"
To=".25" Duration="0:0:0"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup Name="FocusStates">
<VisualState Name="Focused">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="foc"
Storyboard.TargetProperty="Opacity"
To="1" Duration="0:0:.1"/>
</Storyboard>
</VisualState>
<VisualState Name="Unfocused">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="foc"
Storyboard.TargetProperty="Opacity"
To="0" Duration="0:0:.1"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
Как вы перемещаете UserControl с помощью мыши? Используете ли вы RenderTransform? Попробуйте использовать LayoutTransfrom или Canvas.SetTop, Canvas.SetLeft, чтобы переместить ваши кнопки. – bitbonk
да, я использую RenderTransform – Lullaby