Silverlight:来自一个usercontrol的事件可以在不同的usercontrol和/或包含控件上开始动画

时间:2011-10-20 21:19:50

标签: c# wpf silverlight xaml visualstatemanager

我在Silverlight中有三个UserControl。

UCOutside包含两个名为UCInside1和UCInside2的UserControl。

包含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>

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

问题是如何通过Click事件启动所有三个动画?它可以通过XAML或Blend捆绑在一起吗?如果不是如何在c#代码中完成?

2 个答案:

答案 0 :(得分:1)

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

让触发初始事件的容器成为可观察部分,让其他两个人观察它。因此,只要可观察容器执行某些操作(例如触发点击事件),其他人就会得到通知并做出相应的反应。

一旦您的OutsideContainer类可观察,请执行以下两个步骤:

  1. 在OutsideButton类中,在适当的位置触发PropertyChanged事件(例如,“super”-click发生的位置。

  2. 在ImageFade和ButtonFace类中,聊聊PropertyChanged事件并执行某些操作(例如,让他们触发自己的点击事件)。

  3. 尝试以下方法:

    在代码隐藏文件中,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方法得到通知。

    希望能帮助你。

答案 1 :(得分:0)

再次经历之后,我发现有一个更简单的解决方案:)

如果你想在你的OutsideBoard类中做出反应来点击 - 另一个类的事件 - 只需抓住那个特定事件:)

所以在你的“孩子”的代码behinde中简单地写(假设你的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的点击事件将从itselfe进行聊天(没有您的干扰)您所做的只是向该点击触发控件添加额外的EventHandler:)