Search code examples
wpfxamlwpf-style

wpf trigger property IsPressed not working correctly


When I click a Button, the image in it must change and remain changed. I tried to use the Triggers on the Button Style, binding the image to the IsPressed property, but when the Button is released, the image returns the previous one. Please help.

<Button Content="Easy Locate" Height="20" Width="85" Margin="0,2,0,0">
  <Button.Style>
    <Style TargetType="{x:Type Button}">
      <Style.Triggers>
        <Trigger Property="IsPressed" Value="True">
          <Setter Property="Template">
            <Setter.Value>
              <ControlTemplate TargetType="{x:Type Button}">
                <Border BorderThickness="0">
                  <Image Source="/AltusClient;component/Images/waiting.png"
                         Height="20"
                         Width="25"/>
                </Border>
                <!--<ControlTemplate.Triggers>
                  <Trigger Property="IsPressed" Value="True">
                    <Setter Property="Background" Value="Transparent"/>
                    <Setter Property="BorderThickness" Value="0"/>
                  </Trigger>
                </ControlTemplate.Triggers>-->
              </ControlTemplate>
            </Setter.Value>
          </Setter>
        </Trigger>
      </Style.Triggers>
    </Style>
  </Button.Style>
</Button>

Solution

  • Here's an example of a button that works the way you want. You can easily switch the button back to its default state by adding another Trigger to set its Tag property to null, an empty string, or absolutely anything in the world other than "ButtonHasBeenPressed".

    <Button Content="Button Content">
        <Button.Style>
            <Style TargetType="Button">
                <Style.Resources>
                    <ControlTemplate 
                        x:Key="PressedTemplate" 
                        TargetType="Button">
                        <Border 
                            Background="LightSkyBlue" 
                            BorderBrush="DeepSkyBlue" 
                            BorderThickness="4"
                            >
                            <TextBlock 
                                Text="Replace this TextBlock with your own content" 
                                Foreground="ForestGreen" 
                                />
                        </Border>
                    </ControlTemplate>
                </Style.Resources>
                <Style.Triggers>
                    <!-- 
                    We can't set Template directly with DiscreteObjectKeyFrame because 
                    "Cannot freeze this Storyboard timeline tree for use across threads".
    
                    So instead we kludge it by setting Tag and putting a trigger on that. 
                    -->
                    <Trigger 
                        Property="Tag" 
                        Value="ButtonHasBeenPressed"
                        >
                        <Setter 
                            Property="Template" 
                            Value="{StaticResource PressedTemplate}" 
                            />
                    </Trigger>
                    <Trigger Property="IsPressed" Value="True">
                        <!-- 
                        Values set by a Trigger setter are automatically rolled 
                        back when the Trigger condition no longer applies. This 
                        is not true of values applied by a Storyboard in an enter 
                        action. 
                        -->
                        <Trigger.EnterActions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames 
                                        BeginTime="00:00:00" 
                                        Storyboard.TargetProperty="Tag"
                                        >
                                        <DiscreteObjectKeyFrame 
                                            KeyTime="00:00:00" 
                                            Value="ButtonHasBeenPressed" 
                                            />
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.EnterActions>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
    </Button>