Если я правильно понимаю вашу проблему, то вы не хотите повторять одно и то же EventTrigger
несколько раз, по одному разу для каждого источника.Если вы пропустите SourceName
, то ваша анимация запустится для любого необработанного перенаправленного события MouseDown
, даже если оно не от одного из ваших изображений (поскольку MouseDown
является очень общим перенаправленным событием всплывающего).
Одним из решений было бы иметь пользовательский класс Image
(возможно, называемый MyImage
), который будет определять, когда происходит событие MouseDown
, и в ответ запускать очень пользовательский RoutedEvent
(скажем, MyImageRoutedEvent
).Тогда ваш EventTrigger
сможет прослушивать MyImageRoutedEvent
, поскольку только MyImage
может вызвать это событие.Следовательно, ваша анимация запускается только в том случае, если событие MouseDown
происходит от одного из ваших MyImage
экземпляров.
В качестве альтернативы, вы можете достичь этого поведения с помощью присоединенного поведения.Идея состоит в том, что поведение настроено на перехват определенного события (через присоединенное свойство), и когда это событие запускается из элемента, участвующего в поведении, событие помечается как обработанное, и вместо этого запускается новое пользовательское событие.Ваш EventTrigger
будет затем прослушивать новое пользовательское событие.
Пример XAML:
<StackPanel>
<StackPanel.Resources>
<Style x:Key="rectangleStyle" TargetType="{x:Type Rectangle}">
<Setter Property="Width" Value="100" />
<Setter Property="Height" Value="100" />
<Setter Property="l:EventInterceptBehaviour.OriginalRoutedEvent" Value="UIElement.MouseDown" />
</Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContentControl}">
<StackPanel>
<Rectangle Style="{StaticResource rectangleStyle}" Fill="Red" />
<Rectangle Style="{StaticResource rectangleStyle}" Fill="Green" />
<Rectangle Style="{StaticResource rectangleStyle}" Fill="Blue" />
<Border BorderBrush="Black" x:Name="contentBorder">
<ContentPresenter HorizontalAlignment="Center"/>
</Border>
</StackPanel>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="l:EventInterceptBehaviour.InterceptedEvent">
<BeginStoryboard Name="mySlider">
<Storyboard>
<ThicknessAnimation Storyboard.TargetName="contentBorder"
Storyboard.TargetProperty="BorderThickness"
Duration="0:0:1" To="10" FillBehavior="Stop" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</StackPanel.Resources>
<ContentControl Content="Content Placeholder" />
</StackPanel>
Пример поведения:
public static class EventInterceptBehaviour
{
#region InterceptedEvent Attached Routed Event
public static readonly RoutedEvent InterceptedEventEvent = EventManager.RegisterRoutedEvent("InterceptedEvent",
RoutingStrategy.Bubble,
typeof(RoutedEventHandler),
typeof(EventInterceptBehaviour));
public static void AddInterceptedEventHandler(DependencyObject d, RoutedEventHandler handler)
{
if (d is FrameworkElement)
{
var element = (FrameworkElement)d;
element.AddHandler(InterceptedEventEvent, handler);
}
}
public static void RemoveInterceptedEventHandler(DependencyObject d, RoutedEventHandler handler)
{
if (d is FrameworkElement)
{
var element = (FrameworkElement)d;
element.RemoveHandler(InterceptedEventEvent, handler);
}
}
#endregion
#region OriginalRoutedEvent Attached Dependency Property
public static void SetOriginalRoutedEvent(FrameworkElement element, RoutedEvent value)
{
element.SetValue(OriginalRoutedEventProperty, value);
}
public static RoutedEvent GetOriginalRoutedEvent(FrameworkElement element)
{
return (RoutedEvent)element.GetValue(OriginalRoutedEventProperty);
}
public static readonly DependencyProperty OriginalRoutedEventProperty =
DependencyProperty.RegisterAttached("OriginalRoutedEvent", typeof(RoutedEvent),
typeof(EventInterceptBehaviour),
new FrameworkPropertyMetadata(OnOriginalRoutedEventPropertyChanged));
#endregion
private static void OnOriginalRoutedEvent(object sender, RoutedEventArgs e)
{
var element = (FrameworkElement)sender;
element.RaiseEvent(new RoutedEventArgs(InterceptedEventEvent, element));
e.Handled = true;
}
private static void OnOriginalRoutedEventPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is FrameworkElement)
{
var element = (FrameworkElement)d;
element.AddHandler((RoutedEvent)e.NewValue, new RoutedEventHandler(OnOriginalRoutedEvent));
}
}
}
В этом примере стиль имеет видприменяется к каждому Rectangle
, а присоединенное поведение настроено на перехват перенаправленного события MouseDown
и замену этого события на InterceptedEvent
.Анимация запускается только при срабатывании InterceptedEvent
.
Надеюсь, это поможет!