Silverlight: может ли событие из одного пользовательского элемента управления начать анимацию с другого пользовательского элемента управления и / или содержащего его элемента управления

У меня есть три UserControls в Silverlight.

UCOutside содержит два UserControls, которые называются UCInside1 и UCInside2.

Содержит UserControl

<!-- UCOutside --> 
<UserControl.Resources>
    <Storyboard x:Name="OutsideBoard">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)" Storyboard.TargetName="LayoutRoot">
            <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
            <EasingDoubleKeyFrame KeyTime="0:0:1" Value="45"/>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>
</UserControl.Resources>

<Grid x:Name="LayoutRoot">
    <Grid.Projection>
        <PlaneProjection/>
    </Grid.Projection>
    <local:UCInside1 Margin="39,35,266,173"/>
    <local:UCInside2 HorizontalAlignment="Right" Margin="0,234,26,30" />
</Grid>

Первый UserControl Inside

<!-- UCInside1 -->
<UserControl.Resources>
    <Storyboard x:Name="ImageFade">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="myImage">
            <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
            <EasingDoubleKeyFrame KeyTime="0:0:1.5" Value="0.2"/>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Margin="0" HorizontalAlignment="Left" VerticalAlignment="Top">
<Image x:Name="myImage" Margin="0" Source="/OtherImage.png" Stretch="Fill" Width="312" Height="250" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</Grid>

Второй UserControl Inside

<!-- UCInside2 -->
<UserControl.Resources>
    <Storyboard x:Name="ButtonFade">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="image1">
            <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
            <EasingDoubleKeyFrame KeyTime="0:0:1" Value="0"/>
            <EasingDoubleKeyFrame KeyTime="0:0:2" Value="1"/>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>
</UserControl.Resources>

<Grid x:Name="LayoutRoot" HorizontalAlignment="Left" Height="195" VerticalAlignment="Top" Width="218">
    <Button Content="Button" HorizontalAlignment="Right" Margin="0,0,25,51" VerticalAlignment="Bottom" Width="75" Click="ClickButton"/>
    <Image x:Name="image1" HorizontalAlignment="Left" Margin="41,32,0,70" Source="/Whatever.png" Stretch="Fill" Width="47"/>
</Grid>

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

Вопрос в том, как мне запустить все три анимации с помощью события Click? Можно ли все это связать через XAML или используя Blend? Если нет, то как это делается в коде C#?

2 ответа

Решение

Я бы сказал, что очень простой и эффективный способ решить эту проблему - использовать интерфейс INotifyPropertyChanged для использования Observer-Pattern.

Пусть контейнер, который запускает начальное событие, будет наблюдаемой частью, и пусть два других наблюдают за этим. Поэтому всякий раз, когда наблюдаемый контейнер что-то делает (например, запускает событие щелчка), другие будут получать информацию и могут реагировать соответствующим образом.

Как только ваш класс OutsideContainer станет видимым, выполните следующие два шага:

  1. В классе OutsideButton срабатывает событие PropertyChanged в подходящем месте (например, где происходит "супер"-клик).

  2. В классе ImageFade и ButtonFace перехватите событие PropertyChanged и сделайте что-нибудь (например, позвольте им запустить свое собственное событие click).

Попробуйте следующее:

В файле с выделенным кодом OutsideBoard.cs реализует интерфейс INotifyPropertyChanged, чтобы сделать его видимым:

class OutsideBoard : INotifyPropertyChanged {

    public event PropertyChangedEventHandler PropertyChanged;

    private void FirePropertyChanged (string property) {

        if (PropertyChanged != null) {

            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }

    // the click- EventHandler of your UserControl
    public event Click_EventHandler (object sender, RoutedEventArgs e) {

        // your clicking code of your UserControl

        FirePropertyChanged("SuperClick");
    }


    // rest of the code inhere ...
}

Теперь каждый класс, который хочет наблюдать класс OutsideBorder, должен реализовать EventHandler для этого класса:

Напишите что-то вроде следующего в вашем классе ButtonFade и ImageFade:

outsideBorder.PropertyChanged += PropertyEventChangeHandler(MyClickHandling);

public void MyClickHandling (object sender, PropertyChangeEventArgs e) {

     // do something
}

Поэтому всякий раз, когда класс OutsideBoard запускает событие PropertyChanged, все наблюдатели будут получать уведомления, вызывая их метод MyClickHandling.

Надеюсь, что это поможет вам.

Пройдя через это снова, я понял, что может быть гораздо более простое решение:)

Если вы хотите реагировать в своем классе OutsideBoard на щелчок - событие другого класса - просто перехватите это конкретное событие:)

так что в коде ваших "детей" просто напишите (при условии, что ваш класс OutsideBorder находится вне outsideBorder:

outsideBorder.Click += MouseEventHandler(MyClickHandler);

public void MyClickHandler (object sender, MouseEventArgs e) {

    // do something to react on the click appeared in the OutsideBoard class.
}

Таким образом, событие клика на Внешней Доске будет обсуждаться как есть от самого себя (без вашего вмешательства). Что вы делаете, это просто добавляете дополнительный EventHandler к этому элементу управления кликом:)

Другие вопросы по тегам