Home > Software design >  WPF Custom Template button with rounded corners not responding sometimes
WPF Custom Template button with rounded corners not responding sometimes

Time:11-23

Im currently working on a UI with WPF embedded in a ElementHost Control(Winform) for a powerpoint add-in. The appearance for the button works fine, however sometimes when entering the button it simply doesn't respond, meaning that hover/press events are not fired and when I click on it selects the parent behind it (probaly since nothing is selected) as if the button was a ghost. When i remove the border inside the template that displays the rounded rectangle the problem dissapears, a default button also doesnt suffer from the same problem. However if the custom button has focus on it, it works flawlessly. So far my best guess is performance related issues.

Grid inside usercontrol that holds the buttons:

<Viewbox Grid.Column="2" Grid.RowSpan="3" HorizontalAlignment="Right" Margin="0,5,10,5">
   <Grid Height="100" Width="100">
      <Grid.RowDefinitions>
         <RowDefinition/>
         <RowDefinition/>
         <RowDefinition/>
      </Grid.RowDefinitions>
      <Grid.ColumnDefinitions>
         <ColumnDefinition/>
         <ColumnDefinition/>
         <ColumnDefinition/>
      </Grid.ColumnDefinitions>
      
      <Button Grid.Row="0" Grid.Column="0"  Background="red" Style="{StaticResource AnchorPoint}" Click="Button_Click_1"/>
      <!--<Button Grid.Row="0" Grid.Column="1" Style="{StaticResource AnchorPoint}"/>
      <Button Grid.Row="0" Grid.Column="2" Style="{StaticResource AnchorPoint}"/>
      <Button Grid.Row="1" Grid.Column="2" Style="{StaticResource AnchorPoint}"/>
      <Button Grid.Row="1" Grid.Column="1" Style="{StaticResource AnchorPoint}"/>
      <Button Grid.Row="1" Grid.Column="0" Style="{StaticResource AnchorPoint}"/>
      <Button Grid.Row="2" Grid.Column="0" Style="{StaticResource AnchorPoint}"/>
      <Button Grid.Row="2" Grid.Column="1" Style="{StaticResource AnchorPoint}"/>-->
      <Button Grid.Row="2" Grid.Column="2" Style="{StaticResource AnchorPoint}"/>
      <Button Content="Button" Grid.Column="2" Grid.Row="1"/>
   </Grid>
</Viewbox>

Style for button:

<Style TargetType="Button" x:Key="AnchorPoint">
   <Setter Property="Background" Value="Transparent"></Setter>
   <Setter Property="Foreground" Value="Transparent"></Setter>
   <Setter Property="BorderBrush" Value="{x:Null}"></Setter>
   <Setter Property="BorderThickness" Value="0"></Setter>
   <Setter Property="HorizontalAlignment" Value="Stretch"></Setter>
   <Setter Property="VerticalAlignment" Value="Stretch"></Setter>
   <Setter Property="Margin" Value="0,0,0,0"></Setter>

   <Setter Property="Template">
      <Setter.Value>
         <ControlTemplate TargetType="Button">

            <Border x:Name="border" CornerRadius="2" Margin="0" BorderThickness="2" Style="{StaticResource TestHidden}">
            <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" ContentSource="Content"/>
            </Border>

            <ControlTemplate.Triggers>
               <Trigger Property="IsPressed" Value="True">
                  <Setter Property="Background" Value="Red" TargetName="border"></Setter>
               </Trigger>

               <Trigger Property="IsFocused" Value="True">
                  <Setter Property="Background" Value="blue" TargetName="border"></Setter>
               </Trigger>

               <Trigger Property="IsMouseOver" Value="True">
                  <Setter Property="Background" Value="green" TargetName="border"></Setter>
               </Trigger>
            </ControlTemplate.Triggers>

         </ControlTemplate>
      </Setter.Value>
   </Setter>
</Style>

Style for Border:

<Style x:Key="TestHidden" TargetType="Border">
   <Setter Property="BorderBrush" Value="{StaticResource SkyGrey}"/>
   <Setter Property="Background" Value="{x:Null}" />
   <Setter Property="Focusable" Value="False"></Setter>
   <Style.Triggers>
      <Trigger Property="IsMouseOver" Value="True">
         <Setter Property="BorderBrush" Value="{StaticResource SkyGrey}" />
         <Setter Property="Background" Value="{StaticResource SkyGreyHover}" />
      </Trigger>
   </Style.Triggers>
</Style>

CodePudding user response:

My hunch is that the problem is related to setting the Background Property of the Border (Key="TestHidden") default to {x:Null}. Although it seems odd, setting the Background to null for a UIElement can cause the element to be invisible to mouse events. This is probably why the element behind the border is the one capturing mouse events instead - making the border seem like a "Ghost". Set the borders default background to Transparent.

    <Style x:Key="TestHidden" TargetType="Border">
    <Setter Property="BorderBrush" Value="{StaticResource SkyGrey}"/>
    <Setter Property="Background" Value="Transparent" />

You might ask why parent button (Key="AnchorPoint") is not capturing mouse events instead: Although the Buttons Background is correctly set to Transparent, this property is being ignored by WPF because it is not referenced in the ControlTemplate via TemplateBinding. If you want the buttons background property to actually show up in the control, use a TemplateBinding on the control responsible for displaying the Background color (the border):

                <Border x:Name="border" 
                        CornerRadius="2" 
                        Margin="0" 
                        BorderThickness="2" 
                        Style="{StaticResource TestHidden}"
                        Background="{TemplateBinding Background}">
                    <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" ContentSource="Content"/>
                </Border>

Note: There are various other occurrences in your XAML where the issues described above might exist. Hope this helps.

  • Related