В WPF: Раскадровка.TargetName работает, но Setter TargetName не работает
предположим, у нас есть код XAML, как это:
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border HorizontalAlignment="Center" VerticalAlignment="Center">
<Border.LayoutTransform>
<!--We are rotating randomly each image. Selected one will be rotated to 45°.-->
<RotateTransform Angle="{Binding RandomAngle}" x:Name="globalRotation"/>
</Border.LayoutTransform>
<Grid>
<Image Source="{Binding ImageLocation}" Stretch="None" />
<TextBlock x:Name="title" Text="{Binding Title}" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="title" Property="Visibility" Value="Visible"/>
<!--The next line will not compile.-->
<Setter TargetName="globalRotation" Property="Angle" Value="45"/>
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<!--This compiles well.-->
<DoubleAnimation Storyboard.TargetName="globalRotation" Storyboard.TargetProperty="Angle" To="45" Duration="00:00:03"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
этот код предназначен для отображения набора изображений в ListBox. Каждое изображение имеет случайное вращение, но при выборе, поворачивается на 45 градусов.
поворот выбранного изображения через раскадровку работает хорошо. Я просто указываю Storyboard.TargetName
и он поворачивает изображение при выборе (Trigger.ExitActions
опущен, чтобы сделать код короче).
теперь, если я хочу, вместо использования раскадровки, назначьте значение 45 градусов прямо я не могу этого сделать, потому что <Setter TargetName="globalRotation" Property="Angle" Value="45"/>
: он компилирует с
"не удается найти цель триггера "globalRotation". (Цель должна отображаться перед любыми сеттерами, триггерами или условиями, которые ее используют.)"
ошибка. Что происходит? Полагаю, что Storyboard.TargetName
оценивается во время выполнения, так что позвольте мне скомпилировать его. Правильно ли это?
как заставить его работать только с сеттером, без использования раскадровки?
1 ответов
дело в том, что триггер-сеттер может нацеливаться только на объекты FrameworkElement или FrameworkContentElement, тогда как раскадровка работает с любым DependencyProperty.
вот решение:
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="brd" HorizontalAlignment="Center" VerticalAlignment="Center" Tag="{Binding RandomAngle}">
<Border.LayoutTransform>
<!--We are rotating randomly each image. Selected one will be rotated to 45°.-->
<RotateTransform Angle="{Binding ElementName=brd, Path=Tag}" x:Name="globalRotation"/>
</Border.LayoutTransform>
<Grid>
<Image Source="{Binding ImageLocation}" Stretch="None" />
<TextBlock x:Name="title" Text="{Binding Title}" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="title" Property="Visibility" Value="Visible"/>
<!--The next line will not compile.-->
<Setter TargetName="brd" Property="Tag" Value="45"/>
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<!--This compiles well.-->
<DoubleAnimation Storyboard.TargetName="globalRotation" Storyboard.TargetProperty="Angle" To="45" Duration="00:00:03"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>