Billy ONeal
Billy ONeal

Reputation: 106609

How does one make a transparent portion of a button clickable in WPF?

I have a bunch of toolstrip buttons with transparent backgrounds in WPF. When the user mouses over the outside of the button, nothing happens, because that part of the button is transparent. Once the user mouses over one of the non-transparent areas of the button, the "hover" behavior changes the border and background color. The background is no longer transparent, so the hover behavior continues for a much larger area than before. I would like the transparent areas of the button to behave as if the button were non-transparent there.

That is, now I have this behavior where the button is unselected despite the mouse being clearly inside the button area:

Bad Behavior

and I'm trying to get the button to be selected like this even if the user has not previously moused over the foreground "white" part of the button:

Good Behavior

I tried setting IsHitTestVisible on the button itself, but that didn't seem to make any difference.

Is there a way to ask WPF to consider the transparent areas of the button significant?

XAML currently looks like this:

<Button Style="{StaticResource MainToolstripButtonStyle}" Margin="5,0,0,0"
ToolTip="{StaticResource OpenButtonText}"
AutomationProperties.Name="{StaticResource OpenButtonText}"
Command="{StaticResource Open}"
Content="{StaticResource OpenIcon}" />

<Style x:Key="MainToolstripButtonStyle" TargetType="Button">
    <Setter Property="Width" Value="24" />
    <Setter Property="Height" Value="24" />
    <Setter Property="Background" Value="{x:Null}" />
    <Setter Property="Foreground" Value="White" />
    <Setter Property="Padding" Value="0" />
    <!-- If users want to use keyboard navigation, they use the menu instead. -->
    <Setter Property="IsTabStop" Value="False" />
    <Setter Property="Focusable" Value="False"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Border Name="Border"
              BorderThickness="1"
              BorderBrush="{x:Null}">
                    <ContentPresenter HorizontalAlignment="Center"
                          VerticalAlignment="Center" 
                          RecognizesAccessKey="True" />
                </Border>
                <ControlTemplate.Triggers>
                    <!-- Low contrast triggers for selection / focus / enabled: -->
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding Source={x:Static vvm:SystemParametersBindingTarget.Instance}, Path=HighContrast}" Value="False" />
                            <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsMouseOver}" Value="True" />
                            <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsEnabled}" Value="True" />
                        </MultiDataTrigger.Conditions>
                        <Setter TargetName="Border"
                  Property="Background"
                  Value="{StaticResource HotToolbarButtonBrush}" />
                        <Setter TargetName="Border"
                  Property="BorderBrush"
                  Value="{StaticResource HotToolbarButtonBorderBrush}" />
                    </MultiDataTrigger>

                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding Source={x:Static vvm:SystemParametersBindingTarget.Instance}, Path=HighContrast}" Value="False" />
                            <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsEnabled}" Value="False" />
                        </MultiDataTrigger.Conditions>
                        <Setter Property="Foreground"
                  Value="{StaticResource DisabledToolbarButtonBrush}" />
                    </MultiDataTrigger>

                    <!-- High contrast triggers omitted -->
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>  

Upvotes: 1

Views: 2126

Answers (2)

Michael Surma
Michael Surma

Reputation: 11

I have had this problem when I use an image with transparent areas as the look for the button in a style's control template like this:

<Setter Property="Template">
  <Setter.Value>
    <ControlTemplate TargetType="{x:Type Button}">
      <Grid>
        <Image Name="myImage" Source="ProjectImagesFolder/myImage.png">
        </Image>
        <TextBlock Text="{TemplateBinding Content}" TextAlignment="Center"
          VerticalAlignment="Center" />
      </Grid>
    </ControlTemplate>
  </Setter.Value>
</Setter>

The easiest way to fix this is to edit the image in Visual Studio and paint bucket the image transparent areas with the color R=0,G=0,B=0,A=1. It doesn't affect the image but there is now something there.

Upvotes: 1

Clemens
Clemens

Reputation: 128136

Replace

<Setter Property="Background" Value="{x:Null}" />

by

<Setter Property="Background" Value="Transparent" />

and use the Background property in the ControlTemplate:

<ControlTemplate TargetType="{x:Type Button}">
    <Border Name="Border" Background="{TemplateBinding Background}" ...>
        ...
    </Border>
</ControlTemplate>

Upvotes: 8

Related Questions