Silverlight:来自一个用户控件的事件可以在另一个用户控件和/或包含它的控件上开始动画吗?

本文关键字:控件 用户 另一个 包含它 动画 开始 事件 Silverlight 一个 | 更新日期: 2023-09-27 18:12:08

我在Silverlight中有三个UserControls

UCOutside包含两个UserControls,分别叫做UCInside1和UCInside2。

包含用户控件

<!-- 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>

First 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>

Second 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>

您将注意到Button上的ClickButton事件。你还会注意到在所有UserControls中都指定了简单的故事板。

问题是我如何得到所有三个动画开始点击事件?所有这些都可以通过XAML或使用Blend捆绑在一起吗?如果没有,如何在c#代码中完成?

Silverlight:来自一个用户控件的事件可以在另一个用户控件和/或包含它的控件上开始动画吗?

我想说解决这个问题的一个非常简单和有效的方法是使用INotifyPropertyChanged接口,以便使用Observer-Pattern。

让触发初始事件的容器作为可观察部分,并让其他两个容器观察它。因此,无论可观察容器做什么(比如触发click-event),其他容器都会得到通知,并做出相应的反应。

一旦你的外部容器类是可观察的,执行以下两个步骤:

  1. 在OutsideButton类中,在适当的地方触发PropertyChanged事件(例如,在"super"点击发生的地方)

  2. 在ImageFade和ButtonFace类中捕获PropertyChanged事件并做一些事情(例如让它们触发自己的click-event)。

尝试以下操作:

在代码隐藏文件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类中对另一个类的click事件做出反应,只需捕获那个特定的事件:)

所以在你的"孩子"代码后面简单地写(假设你的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.
}

所以OutsideBoard的click-event会从它自己那里得到chatched(没有你的干扰)你要做的就是简单地添加额外的EventHandler到那个click-firing控件:)