2013-01-14 3 views
0

У меня есть UserControl с некоторыми кнопками. Моя кнопка имеет значение FocusVisualStyle по умолчанию (граница вокруг кнопки).WPF - FocusVisualStyle при перемещении

Когда я перемещаю свой элемент управления с помощью мыши, эта пунктирная рамка не перемещается вместе с ней. Когда вы наводите курсор на другую часть экрана, он перемещается в правильное положение.

Я не хочу, чтобы FocusVisualStyle был нулевым, потому что мне нужно увидеть, какой элемент сфокусирован. Я попытался создать свой собственный FocusVisualStyle, но он ведет себя как по умолчанию.

Могу ли я каким-то образом синхронизировать эту границу с остальными элементами?

Спасибо за помощь

+0

Как вы перемещаете UserControl с помощью мыши? Используете ли вы RenderTransform? Попробуйте использовать LayoutTransfrom или Canvas.SetTop, Canvas.SetLeft, чтобы переместить ваши кнопки. – bitbonk

+0

да, я использую RenderTransform – Lullaby

ответ

2

Как заявлено bitbonk, RenderTransform не вызывает другой аранжировочный проход, чтобы зрительный фокус не двигался. Вы можете прочитать this Dr. WPF article, в котором обсуждается проблема, а также предоставляется несколько обходных решений. Самый простой в вашем случае - просто поместить AdornerDecorator в свой UserControl вокруг содержимого вашего UserControl, чтобы перемещать AdornerLayer тоже.

+0

Большое спасибо. Очень простое исправление – Lullaby

0

При использовании RenderTransformFocusVisualStyle прямоугольник не перемещается с помощью кнопки, потому что он визуализируется в передаче макета. В этом весь смысл RenderTransform: преобразуйте любой визуал и игнорируйте макет остальной части визуального дерева.

Вы должны будете использовать LayoutTransform или Button.Margin или Canvas.Left, Canvas.Top переместить кнопку.

0

Это (зашифрованный) отрывок из MSDN говорит о более общей форме этого вопроса:

Фокуса визуальных стилей действуют исключительно для фокус клавиатуры. Таким образом, фокус визуальных стилей является типом функции доступности. Если вы хотите, чтобы изменения пользовательского интерфейса для любого типа фокуса, будь то с помощью мыши, клавиатуры или программно, тогда вы не должны использовать фокусные визуальные стили и вместо этого должны использовать сеттеры и триггеры в стилях или шаблонах, которые работают со значением общих свойств фокусировки таких как IsFocused или IsFocusWithin.

Сегодня последний бит об использовании триггеров, вероятно, будет лучше заменен предложением о том, что вы используете диспетчер визуальных состояний. Вот некоторые XAML, которые делают это таким образом, но также сохраняет исходную настройку Button's FocusVisualStyle. Эта настройка рисует пунктирный прямоугольник двумя пикселями внутри Button, когда он получает фокус с клавиатуры. Мои Storyboard s для Focused и Unfocused визуальных состояний добавляют и удаляют сплошной прямоугольник, четыре пикселя внутри Button, всякий раз, когда он получает или теряет фокус по любой причине.

Если создать пару Button с в WPF окна и манипулировать фокус с помощью клавиатуры и мыши, нажав эти Button S с пробела и мыши, вы увидите, что Button часто имеет фокус, когда FocusVisualStyle не отображается. Опять же, это (в соответствии с выдержкой выше) по дизайну. (Я озадачен тем, как это «функция доступности», так как это может легко игнорировать, чтобы показать, какой элемент управления будет нажат при следующем нажатии на клавишу пробела. Моя склонность просто не использовать его вообще.)

ПРИМЕЧАНИЕ. Код ниже предназначен для пользовательского элемента управления, полученного из Button, называемого «XLButton». Вы можете изменить StyleTargetType на 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> 
Смежные вопросы