WPF将XAML动画转换为C#代码

时间:2011-10-20 20:11:34

标签: c# wpf animation

我在这里找到了一个很棒的WIPE动画:http://www.wearerighteous.com/programming/slidewipe-transition-for-your-windows-in-wpf/

  编辑:上面的链接已经死了,所以你必须看到这个   http://learnwpf.com/post/2006/10/03/How-can-I-create-a-e2809cwipee2809d-effect-to-transition-between-two-images-in-WPF.aspx   它具有相同的源代码。

基本上,代码就像这样:

<Window.OpacityMask>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
    <GradientStop Offset="0" Color="Black" x:Name="BlackStop"/>
    <GradientStop Offset="0" Color="Transparent" x:Name="TransparentStop"/>
</LinearGradientBrush> 
<Window.OpacityMask>
    <Window.Triggers>
    <EventTrigger RoutedEvent="Window.Loaded">
        <EventTrigger.Actions>
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation Storyboard.TargetName="TransparentStop"
                      Storyboard.TargetProperty="Offset" By="1"  Duration="0:0:1"/>
                    <DoubleAnimation Storyboard.TargetName="BlackStop"
                      Storyboard.TargetProperty="Offset" By="1" Duration="0:0:1"
                      BeginTime="0:0:0.05" />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger.Actions>
    </EventTrigger>
</Window.Triggers>

我试图用c#代码“翻译”动画,我似乎无法做到。我试过几个版本,比如:

public void WipeAnimation(FrameworkElement ObjectToAnimate)
    { 
        LinearGradientBrush OpacityBrush = new LinearGradientBrush();
        OpacityBrush.StartPoint = new Point(1,0);
        OpacityBrush.EndPoint   = new Point(0,0);
        GradientStop BlackStop = new GradientStop(Colors.Black, 0);
        GradientStop TransparentStop = new GradientStop(Colors.Transparent, 0);
        OpacityBrush.GradientStops.Add(t);
        OpacityBrush.GradientStops.Add(t2);
        ObjectToAnimate.OpacityMask = OpacityBrush;

        Duration d = TimeSpan.FromSeconds(4);
        Storyboard sb = new Storyboard() { Duration = d };
        DoubleAnimation DA = new DoubleAnimation() {  By=1 , Duration = d };
        DoubleAnimation DA2 = new DoubleAnimation() { By=1 , Duration = d };
        sb.Children.Add(DA); sb.Children.Add(DA2);
        Storyboard.SetTarget(DA,TransparentStop);
        Storyboard.SetTarget(DA2,BlackStop);
        Storyboard.SetTargetProperty(DA, new PropertyPath("Offset"));
        Storyboard.SetTargetProperty(DA2, new PropertyPath("Offset"));
        sb.Begin();
    }

或者替换SetTarget行,如:

Storyboard.SetTarget(DA, (ObjectToAnimate.OpacityMask as LinearGradientBrush).GradientStops[1]);

但我的FrameworkElement没有任何反应。我把它称为一个窗口(就像在网站的例子中一样),唯一的想法是它设置了OpacityMask。动画开始和结束(我使用MessageBox向Storyboard添加了一个Completed Event以查看它是否有效)。我不知道还有别的事情要做。

请帮忙! :( 有什么想法吗?

修改 也许我解释了这个问题。我正在尝试使用C#代码创建我在XAML中的动画....我已经尝试了两天,寻找解决方案。我不知道为什么C#版本不起作用......

3 个答案:

答案 0 :(得分:1)

我不确定上面的原因是什么,但是这里确实有效 - 而不是创建一个Storyboard,只需对每个GradientStop使用BeginAnimation()方法:

BlackStop.BeginAnimation(GradientStop.OffsetProperty, DA2);
TransparentStop.BeginAnimation(GradientStop.OffsetProperty, DA);

答案 1 :(得分:1)

public void WipeAnimation(FrameworkElement ObjectToAnimate)
{ 
    LinearGradientBrush OpacityBrush = new LinearGradientBrush();
    OpacityBrush.StartPoint = new Point(1,0);
    OpacityBrush.EndPoint   = new Point(0,0);
    GradientStop BlackStop = new GradientStop(Colors.Black, 0);
    GradientStop TransparentStop = new GradientStop(Colors.Transparent, 0);
    OpacityBrush.GradientStops.Add(t);
    OpacityBrush.GradientStops.Add(t2);
    ObjectToAnimate.OpacityMask = OpacityBrush;

    this.RegisterName("TransparentStop", TransparentStop);
    this.RegisterName("BlackStop", BlackStop);

    Duration d = TimeSpan.FromSeconds(4);
    Storyboard sb = new Storyboard() { Duration = d };
    DoubleAnimation DA = new DoubleAnimation() {  By=1 , Duration = d };
    DoubleAnimation DA2 = new DoubleAnimation() { By=1 , Duration = d };
    sb.Children.Add(DA); sb.Children.Add(DA2);
    Storyboard.SetTargetName(DA,"TransparentStop");
    Storyboard.SetTargetName(DA2,"BlackStop");
    Storyboard.SetTargetProperty(DA, new PropertyPath("Offset"));
    Storyboard.SetTargetProperty(DA2, new PropertyPath("Offset"));
    sb.Begin();
}

编辑:

这段代码很棒!但它有3个错误,所以我发现它。正确的版本在这里:

 public void WipeAnimation(FrameworkElement ObjectToAnimate)
        {
            LinearGradientBrush OpacityBrush = new LinearGradientBrush();
            OpacityBrush.StartPoint = new Point(1, 0);
            OpacityBrush.EndPoint = new Point(0, 0);
            GradientStop BlackStop = new GradientStop(Colors.Black, 0);
             GradientStop TransparentStop = new GradientStop(Colors.Transparent, 0);
            OpacityBrush.GradientStops.Add(BlackStop);
            OpacityBrush.GradientStops.Add(TransparentStop);
            ObjectToAnimate.OpacityMask = OpacityBrush;

            this.RegisterName("TransparentStop", TransparentStop);
            this.RegisterName("BlackStop", BlackStop);

            Duration d = TimeSpan.FromSeconds(4);
            Storyboard sb = new Storyboard() { Duration = d };
            DoubleAnimation DA = new DoubleAnimation() { By = 1, Duration = d };
            DoubleAnimation DA2 = new DoubleAnimation() { By = 1, Duration = d };
            sb.Children.Add(DA); sb.Children.Add(DA2);
            Storyboard.SetTargetName(DA, "TransparentStop");
            Storyboard.SetTargetName(DA2, "BlackStop");
            Storyboard.SetTargetProperty(DA, new PropertyPath("Offset"));
            Storyboard.SetTargetProperty(DA2, new PropertyPath("Offset"));
            sb.Begin(this);
        }

错误行是:

OpacityBrush.GradientStops.Add(t); ->  OpacityBrush.GradientStops.Add(BlackStop);

OpacityBrush.GradientStops.Add(t2); -> OpacityBrush.GradientStops.Add(TransparentStop);

sb.Begin(); ->  sb.Begin(this);

答案 2 :(得分:-1)

似乎在我的案例中工作得很好.....

 <Window x:Class="WpfHierarchicalDataGrid.Window4"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window4" 
    MinHeight="100"
    MinWidth="100"
    AllowsTransparency="True"
    Opacity="0.7"
    WindowState="Normal"
    WindowStyle="None">
  <Window.OpacityMask>
    <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
        <GradientStop Offset="0" Color="Black"
                      x:Name="BlackStop"/>
        <GradientStop Offset="0" Color="Transparent"
                      x:Name="TransparentStop"/>
    </LinearGradientBrush>
  </Window.OpacityMask>
  <Window.Triggers>
    <EventTrigger RoutedEvent="Window.Loaded">
        <EventTrigger.Actions>
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation 
                        Storyboard.TargetName="TransparentStop"
                        Storyboard.TargetProperty="Offset"
                        By="1"  Duration="0:0:1"/>
                    <DoubleAnimation
                       Storyboard.TargetName="BlackStop"
                       Storyboard.TargetProperty="Offset" By="1"
                       Duration="0:0:1"
                       BeginTime="0:0:0.05" />
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger.Actions>
    </EventTrigger>
  </Window.Triggers>
  <Grid>
    <Image Source="Water_lilies.jpg" Stretch="UniformToFill" />
  </Grid>
</Window>