wpf 触发器 属性 IsPressed 无法正常工作
wpf trigger property IsPressed not working correctly
当我点击一个Button
时,其中的图像必须改变并且保持改变。我尝试在Button
Style
上使用Triggers
,将图像绑定到IsPressed
属性,但是当Button
被释放时,图片 returns 上一张。请帮忙。
<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>
这是一个按您想要的方式工作的按钮示例。您可以通过添加另一个 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>
您也可以使用代码隐藏。
假设按钮是:
<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;
这样设置一个private flag,在Button_Click
方法上设置。
您还可以在 Window(或 UserControl)初始化时尽早加载新图像。
最后,我建议您将所有图像放在 ResourceDictionary
中,并通过 StaticResource
Key
在整个应用程序中调用它们,而不是到处使用 URI。但那是另一个话题了。
当我点击一个Button
时,其中的图像必须改变并且保持改变。我尝试在Button
Style
上使用Triggers
,将图像绑定到IsPressed
属性,但是当Button
被释放时,图片 returns 上一张。请帮忙。
<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>
这是一个按您想要的方式工作的按钮示例。您可以通过添加另一个 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>
您也可以使用代码隐藏。
假设按钮是:
<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;
这样设置一个private flag,在Button_Click
方法上设置。
您还可以在 Window(或 UserControl)初始化时尽早加载新图像。
最后,我建议您将所有图像放在 ResourceDictionary
中,并通过 StaticResource
Key
在整个应用程序中调用它们,而不是到处使用 URI。但那是另一个话题了。