Roni Hoffman
Roni Hoffman

Reputation: 332

How do I make a button shape a custom Path in WPF?

I have a button using the ControlTemplate below.

<ControlTemplate x:Key="ControlTemplate" TargetType="{x:Type Button}">
        <Grid>
            <Path x:Name="ButtonPath" Fill="{Binding IsSelected, Converter={StaticResource ArrowBackgroundColorConverter}, UpdateSourceTrigger=PropertyChanged}"  
                  Data="{Binding Converter={StaticResource ArrowPathSelector}}" Stretch="UniformToFill" Margin="0 0 -35 0"></Path>
            <TextBlock Grid.Column="0" Grid.Row="0" FontFamily="{StaticResource ApplicationFont}" FontSize="{StaticResource Heading3}" HorizontalAlignment="Center" Margin="35 0 0 0" VerticalAlignment="Center" Text="{Binding Title}" Foreground="White"/>
        </Grid>
    </ControlTemplate>

but when I click the Button in my app it is not outlining the Path but instead the original Button.

I cant quite figure out how to get the button to reflect the Path itself. Any help is greatly appreciated, Thanks!

Upvotes: 0

Views: 3560

Answers (2)

Mike Strobel
Mike Strobel

Reputation: 25623

If you want to change the shape of the focus rectangle (the dotted border indicating keyboard focus), you need to create a custom FocusVisualStyle that draws a dotted path in the same shape as your button content:

<Style x:Key="ButtonFocusRectangle" TargetType="Control">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate>
        <Path Stroke="Black"
              StrokeDashArray="2 2"  
              Data="M 0,0 50,50 100,0 Z"
              Stretch="UniformToFill"
              Margin="0 0 -35 0" />
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

Then, on the button, set FocusVisualStyle="{StaticResource ButtonFocusRectangle}". Note that it would probably be cleaner to define a custom Style for the button, and have it apply both the Template and FocusVisualStyle for you.

Alternatively, you can just get rid of the focus visual entirely by setting FocusVisualStyle="{x:Null}". You might opt to do this, and simply draw a focus hint in your regular Template by, for example, changing the path's stroke with an IsKeyboardFocused trigger.

As an aside, you probably want to set Stretch to Uniform on the paths in both templates. UniformToFill can cause clipping.

Upvotes: 1

DAVEWASLIN
DAVEWASLIN

Reputation: 159

Have you tried putting your Path and your textblock the other way around:

<ControlTemplate x:Key="ControlTemplate" TargetType="{x:Type Button}">
    <Grid>
        <TextBlock Grid.Column="0" Grid.Row="0" FontFamily="{StaticResource ApplicationFont}" FontSize="{StaticResource Heading3}" HorizontalAlignment="Center" Margin="35 0 0 0" VerticalAlignment="Center" Text="{Binding Title}" Foreground="White"/>
        <Path x:Name="ButtonPath" Fill="{Binding IsSelected, Converter={StaticResource ArrowBackgroundColorConverter}, UpdateSourceTrigger=PropertyChanged}"  
              Data="{Binding Converter={StaticResource ArrowPathSelector}}" Stretch="UniformToFill" Margin="0 0 -35 0"></Path>
    </Grid>
</ControlTemplate>

Upvotes: 0

Related Questions