Свойство триггера wpf IsPressed не работает правильно
Когда я нажимаю Button
, изображение в нем должно измениться и оставаться измененным. Я пытался использовать Triggers
на Button
Style
, привязав изображение к 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>
2 ответа
Вот пример кнопки, которая работает так, как вы хотите. Вы можете легко переключить кнопку обратно в ее состояние по умолчанию, добавив еще один 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;
и установить его на Button_Click
метод.
Вы также можете загрузить новое изображение заранее при инициализации Window (или UserControl).
В конце концов, я предлагаю вам поместить все изображения в ResourceDictionary
и вызывать их через приложение через StaticResource
Key
и не используя все URI. Но это другая тема.