【问题标题】:wpf trigger property IsPressed not working correctlywpf 触发器属性 IsPressed 无法正常工作
【发布时间】:2016-10-11 22:10:45
【问题描述】:

当我单击Button 时,其中的图像必须更改并保持更改。我尝试在ButtonStyle上使用Triggers,将图像绑定到IsPressed属性,但是当Button被释放时,图像返回前一个。请帮忙。

<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>

【问题讨论】:

  • 您是说IsPressed 状态只有在您继续按下按钮时才会持续存在?这就是IsPressed 的意思。您是说要在单击时永久更改按钮内容?
  • 是的。这正是我想要的。我是怎么做到的。
  • 我认为您应该能够使用触发器 EnterActions 中的情节提要来做到这一点,但这有点痛苦。一会儿回来。
  • 如果您有示例代码,请帮忙

标签: wpf xaml wpf-style


【解决方案1】:

这是一个按您想要的方式工作的按钮示例。您可以通过添加另一个Trigger 将其Tag 属性设置为null、空字符串或绝对除"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>

【讨论】:

  • 感谢 Ed 让我试一试。
【解决方案2】:

您也可以使用代码隐藏。

假设按钮是:

<Button Click="Button_Click">
  <Image Source="/Image1.png"/>
</Button>

那么,后面的代码可能是:

private void Button_Click(object sender, RoutedEventArgs e)
{
    var b = sender as Button;

    if (b == null)
        return;

    var image = new Image { Source = GetImageSource(), };

    b.Content = image;
}

private BitmapImage GetImageSource()
{
    var imageSource = new BitmapImage();

    imageSource.BeginInit();
    imageSource.UriSource = new Uri("/Image2.png", UriKind.Relative);
    imageSource.EndInit();

    return imageSource;
}

这是一个简化版本,每次用户点击时都会加载新图像。如果你想避免不必要的二次加载,你可以设置一个私有标志,如private bool _imageSet;,并在Button_Click方法上设置。

您还可以在窗口(或用户控件)初始化的早期加载新图像。

最终,我建议您将所有图像放在ResourceDictionary 中,并通过StaticResource Key 在整个应用程序中调用它们,而不是到处使用URI。但这是另一个话题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-24
    • 1970-01-01
    • 1970-01-01
    • 2012-02-25
    • 2015-12-02
    • 1970-01-01
    • 2012-01-04
    • 1970-01-01
    相关资源
    最近更新 更多