我有一個用戶控件與一些按鈕。我的按鈕具有默認的FocusVisualStyle(按鈕周圍的邊框)。WPF - FocusVisualStyle on moving
當我用鼠標移動我的用戶控件時,此虛線邊框不隨它移動。當您將鼠標懸停在屏幕的另一部分上時,它會移動到正確的位置。
我不想將FocusVisualStyle設置爲null,因爲我需要查看哪些元素的焦點。我試圖創建自己的FocusVisualStyle,但其行爲與默認類似。
我可以以某種方式將此邊框與其餘元素同步嗎?
感謝您的幫助
我有一個用戶控件與一些按鈕。我的按鈕具有默認的FocusVisualStyle(按鈕周圍的邊框)。WPF - FocusVisualStyle on moving
當我用鼠標移動我的用戶控件時,此虛線邊框不隨它移動。當您將鼠標懸停在屏幕的另一部分上時,它會移動到正確的位置。
我不想將FocusVisualStyle設置爲null,因爲我需要查看哪些元素的焦點。我試圖創建自己的FocusVisualStyle,但其行爲與默認類似。
我可以以某種方式將此邊框與其餘元素同步嗎?
感謝您的幫助
如bitbonk所述,RenderTransform不會導致另一個排列傳遞,因此焦點視覺不會移動。您可以閱讀this Dr. WPF article,其中討論了該問題並提供了一些解決方法。在你的情況下最簡單的方法就是在你的用戶控件的UserControl內部放置一個AdornerDecorator,這樣AdornerLayer就可以移動了。
非常感謝。很容易修復 – Lullaby
當您使用RenderTransform
,因爲它是在佈局傳遞呈現的FocusVisualStyle
矩形沒有與按鈕移動。這是RenderTransform
的全部要點:轉換任何視覺效果並忽略其餘視覺樹的佈局。
您將不得不使用LayoutTransform
或Button.Margin
或Canvas.Left
,Canvas.Top
移動您的按鈕。
從MSDN這(略帶神祕的)摘錄講這個問題的更一般的形式:
焦點視覺樣式專門行事鍵盤焦點。因此,焦點視覺樣式是一種可訪問性功能。如果您希望對任何類型的焦點進行UI更改(無論是通過鼠標,鍵盤還是以編程方式進行),則不應使用焦點視覺樣式,而應在使用常規焦點屬性值的樣式或模板中使用設置器和觸發器如IsFocused或IsFocusWithin。
今天,關於使用觸發器的最後一點可能會更好地替換爲使用Visual State Manager的建議。這裏有一些XAML可以這樣做,但也保留了Button
的FocusVisualStyle
的原始設置。當設置從鍵盤接收焦點時,該設置在Button
內繪製一個虛線矩形兩個像素。我的Storyboard
s爲Focused
和Unfocused
視覺狀態添加和刪除一個實心的矩形,在一個Button
內的四個像素,每當它由於任何原因獲得或失去焦點時。
如果創建一個WPF窗口一對Button
s,不鍵盤和鼠標操作的焦點,點擊那些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