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 станет видимым, выполните следующие два шага:
В классе OutsideButton срабатывает событие PropertyChanged в подходящем месте (например, где происходит "супер"-клик).
В классе 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 к этому элементу управления кликом:)