9

I have a simply buttonStyle defined for TargetType of Button; but setting the style to button gives an exeption.

<Window>
    <Window.Resources>
        <Style x:Key="buttonStyle" TargetType="{x:Type Button}">
            <Setter Property="Background" Value="Magenta"/>
        </Style>
    </Window.Resources>
    <StackPanel Orientation="Horizontal">
        <Button Content="1" FocusVisualStyle="{StaticResource buttonStyle}"/>
    </StackPanel>
</Window>

Additional information: 'Button' TargetType does not match type of element 'Control'.


Further, setting the TargetType as Control removes the run-time error, but visual style of button doesn't change when it gets Focus.


Style works when set as Button.Style


Edit I have two specific questions:

  1. I agree to the fact that FocusVisualStyle is a property of FrameworkElement and FrameworkContentElement, but why is there an error setting it on button, despite the fact that Style is a namedstyle and not a typedstyle ?

  2. Why does FocusVisualStyle don't get rendered on the Button? Is the Button.FocusVisualStyle over-ridden internally by any higher priority value like Templates, Triggers or Template Triggers ?

Marshal
  • 6,551
  • 13
  • 55
  • 91

3 Answers3

7

a FocusVisualStyle allows you to provide visual feedback to the user when a control is focused. For example, adding a Rectangle which looks like a border of the control.

A Style is the look and feel of the control itself. It's all explained here.

FocusVisualStyle is not the style for the Button itself, it's the style for when the Button is focused.

See here for more information.

I think what you are after is a Trigger.

<Style x:Key="buttonStyle" TargetType="{x:Type Button}">
    <Style.Triggers>
        <Trigger Property="IsFocused" Value="True">
            <Setter Property="Background" Value="Magenta"/>
        </Trigger>
    </Style.Triggers>
</Style>

Then, you can set the Style of your Button, like so:

<Button Style="{StaticResource buttonStyle}" ... />
Mike Eason
  • 9,525
  • 2
  • 38
  • 63
  • I agree, but when the Button gets focus, its style doesn't change. Or am I getting the concept wrong ? – Marshal Jun 12 '15 at 13:55
  • 2
    To clarify, the `FocusVisualStyle` cannot affect the style of the `Button`. It only adds to the existing style of the `Button`. The problem you are having is that you are trying to set a `Button` style to the `FocusVisualStyle` which only accepts a `Control` style. I hope I explained that well enough. – Mike Eason Jun 12 '15 at 13:58
  • It was not working for me for a while as I was setting the same property of the style in line for the button control. In-line property value was overriding what gets set by the style trigger "buttonStyle". Sweet answer! – RBT Dec 16 '15 at 13:28
2

You should use it like this

        <Style x:Key="buttonStyle" TargetType="{x:Type Button}">
            <Style.Triggers>
                <Trigger Property="IsFocused" Value="True">
                    <Setter Property="Background" Value="Magenta" />
                </Trigger>
            </Style.Triggers>
        </Style>

and set it like this:

<Button Content="1" Style="{StaticResource buttonStyle}"/>

To see this better:

         <Style x:Key="buttonStyle" TargetType="{x:Type Button}">
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Background" Value="Magenta" />
                </Trigger>
            </Style.Triggers>
        </Style>

From MSDN

The focus visual style feature provides a common "object model" for introducing visual user feedback based on keyboard navigation to any UI element. This is possible without applying a new template to the control, or knowing the specific template composition.

Olaru Mircea
  • 2,570
  • 26
  • 49
1

To illustrate the difference between button and focus visual style, consider this:

<Style x:Key="rectFocusVisual" TargetType="{x:Type Rectangle}">
  <Setter Property="Margin" Value="2" />
  <Setter Property="SnapsToDevicePixels" Value="true" />
  <Setter Property="Stroke" Value="Red" />
  <Setter Property="StrokeThickness" Value="1" />
  <Setter Property="StrokeDashArray" Value="1 3" />
</Style>
<Style x:Key="focusVisual">
  <Setter Property="Control.Template">
    <Setter.Value>
      <ControlTemplate>
        <Rectangle Style="{StaticResource rectFocusVisual}" />
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>
<Style x:Key="button" TargetType="{x:Type Button}">
  <Setter Property="Background" Value="Green" />
</Style>

and:

<Button
  Content="I am a green button with red focus rectangle"
  FocusVisualStyle="{StaticResource focusVisual}"
  Style="{StaticResource button}" />
<ComboBox FocusVisualStyle="{StaticResource focusVisual}" />

The difference will be apparent when the button is given focus. The button should appear green and if focused will show a red focus rectangle. If the combo box gets focus, it will have a similar red rectangle.

While the button style can only be used for Button elements, the focusVisual style can be used for any element that supports it. This way a consistent focus style can be used for any element, regardless of its underlying control type.

Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
Daap
  • 345
  • 4
  • 10