Запустить раскадровку в WPF? - PullRequest
1 голос
/ 30 ноября 2011

У меня есть много тезисов:

<Image x:Name="Foo" Grid.Column="0" Grid.Row="0" Source="1.png" Style="{StaticResource imageStyle}" 
                       ToolTipService.InitialShowDelay="0" ToolTipService.ShowDuration="360000" ToolTipService.BetweenShowDelay="10000" ToolTip="fffffff"/>

<Image x:Name="Foo2" Grid.Column="1" Grid.Row="0" Source="2.png" Style="{StaticResource imageStyle}" 
                       ToolTipService.InitialShowDelay="0" ToolTipService.ShowDuration="360000" ToolTipService.BetweenShowDelay="10000" ToolTip="eeeeeeeee"/>

<Image x:Name="Foo3" Grid.Column="2" Grid.Row="0" Source="3.png" Style="{StaticResource imageStyle}" 
                       ToolTipService.InitialShowDelay="0" ToolTipService.ShowDuration="360000" ToolTipService.BetweenShowDelay="10000" ToolTip="ddddddddddddd"/>

И сейчас моя анимационная раскадровка срабатывает только тогда, когда кто-то нажимает на Foo изображение.

<Grid.Triggers>
    <EventTrigger RoutedEvent="Image.MouseDown" SourceName="Foo">
        <BeginStoryboard Name="mySlider">
            <Storyboard>
                <ThicknessAnimation Storyboard.TargetName="contentHolder"
                                    Storyboard.TargetProperty="Margin"
                                    Duration="0:0:1" From="0 0 0 0" To="-800 0 0 0" />
            </Storyboard>
        </BeginStoryboard>
    </EventTrigger>
</Grid.Triggers>

Как запустить анимацию, если кто-нибудь нажмет на одно из трех изображений выше? Общим для них является стиль, так что, может быть, есть какой-то способ использовать это?

Есть предложения?

Ответы [ 2 ]

1 голос
/ 01 декабря 2011

Если Grid с триггером является родителем для всех этих изображений, то событие MouseDown будет всплыть до него из каждого изображения в любом случае, поэтому все, что вам нужно сделать, это удалить настройку SourceName из триггера.

В противном случае вы можете установить SourceName в качестве родителя изображения.

1 голос
/ 01 декабря 2011

Если я правильно понимаю вашу проблему, то вы не хотите повторять одно и то же 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.

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...