如何在UWP App

时间:2017-08-02 20:20:19

标签: c# xaml animation uwp uwp-xaml

在我的UWP应用程序中,我有一个包含2列的网格。该应用程序是自适应的,在移动设备上我只想一次显示一列。有没有办法使用动画来减少第1列的宽度并从第2列扩展宽度,反之亦然?

2 个答案:

答案 0 :(得分:11)

在XAML框架中,动画大小和布局一直很棘手。为什么?不是因为你无法为Width制作动画,而是因为对Width / Height的更改会自动触发布局更新,然后进行大量重新计算,性能通常很糟糕,在UI线程上重新测量和重新安排会损害性能的东西。

但是你总能做一些变通办法。使用 Windows Composition API ,现在可以更轻松地制作布局更改动画,同时保持 60 每秒帧数的新鲜率,这一切都要归功于新的API,例如ImplicitAnimationsSetImplicitHideAnimation & SetImplicitShowAnimation

ImplicitAnimations基本上允许您监控属性更改,例如OpacityOffsetSize等,每当更新时,旧值都会动画为新值价值顺利;其中SetImplicitHideAnimation& SetImplicitShowAnimation只会在元素的Visibility更改时生成动画。因此,不是立即消失,而是一个元素可以缩小并淡出。

请注意,您需要为API提供所需的动画,以了解如何设置动画。为了让您的生活更轻松,我创建了一些辅助方法(请参见底部的链接),它封装了您通常需要的一些关键动画。

要了解他们的具体信息,请查看下面的 gif

enter image description here

我正在重新定位,隐藏和显示不同自适应视觉状态中的元素,没有动画在XAML中编写,但使用以下代码, Composition API 只是负责隐含地动画所有这些变化。

var compositor = this.Visual().Compositor;

// Create background visuals.
var leftBackgroundVisual = compositor.CreateSpriteVisual();
leftBackgroundVisual.Brush = compositor.CreateColorBrush(Colors.Crimson);
LeftGridBackgroundVisualWrapper.SetChildVisual(leftBackgroundVisual);

var middleBackgroundVisual = compositor.CreateSpriteVisual();
middleBackgroundVisual.Brush = compositor.CreateColorBrush(Colors.Gold);
MiddleGridBackgroundVisualWrapper.SetChildVisual(middleBackgroundVisual);

var rightBackgroundVisual = compositor.CreateSpriteVisual();
rightBackgroundVisual.Brush = compositor.CreateColorBrush(Colors.DarkOrchid);
RightGridBackgroundVisualWrapper.SetChildVisual(rightBackgroundVisual);

// Sync background visual dimensions.
LeftGridBackgroundVisualWrapper.SizeChanged += (s, e) => leftBackgroundVisual.Size = e.NewSize.ToVector2();
MiddleGridBackgroundVisualWrapper.SizeChanged += (s, e) => middleBackgroundVisual.Size = e.NewSize.ToVector2();
RightGridBackgroundVisualWrapper.SizeChanged += (s, e) => rightBackgroundVisual.Size = e.NewSize.ToVector2();

// Enable implilcit Offset and Size animations.
LeftText.EnableImplicitAnimation(VisualPropertyType.Offset, 400);
MiddleText.EnableImplicitAnimation(VisualPropertyType.Offset, 400);
RightText.EnableImplicitAnimation(VisualPropertyType.Offset, 400);
LeftGrid.EnableImplicitAnimation(VisualPropertyType.Offset, 400);
MiddleGrid.EnableImplicitAnimation(VisualPropertyType.Offset, 400);
RightGrid.EnableImplicitAnimation(VisualPropertyType.Offset, 400);
leftBackgroundVisual.EnableImplicitAnimation(VisualPropertyType.Size, 400);
middleBackgroundVisual.EnableImplicitAnimation(VisualPropertyType.Size, 400);
rightBackgroundVisual.EnableImplicitAnimation(VisualPropertyType.Size, 400);

// Enable implicit Visible/Collapsed animations.
LeftGrid.EnableFluidVisibilityAnimation(showFromScale: 0.6f, hideToScale: 0.8f, showDuration: 400, hideDuration: 250);
MiddleGrid.EnableFluidVisibilityAnimation(showFromScale: 0.6f, hideToScale: 0.8f, showDelay: 200, showDuration: 400, hideDuration: 250);
RightGrid.EnableFluidVisibilityAnimation(showFromScale: 0.6f, hideToScale: 0.8f, showDelay: 400, showDuration: 400, hideDuration: 250);

有很多代码,所以我不会在这里发布所有内容。但请随时从this link查看。

答案 1 :(得分:1)

您可以使用bind来执行此操作。你应该在Page中创建两个属性,代码在下面。

   public static readonly DependencyProperty RcProperty = DependencyProperty.Register(
        "Rc", typeof(double), typeof(MainPage), new PropertyMetadata(100d));

    public double Rc
    {
        get { return (double) GetValue(RcProperty); }
        set { SetValue(RcProperty, value); }
    }

    public static readonly DependencyProperty LcProperty = DependencyProperty.Register(
        "Lc", typeof(double), typeof(MainPage), new PropertyMetadata(500d));

    public double Lc
    {
        get { return (double) GetValue(LcProperty); }
        set { SetValue(LcProperty, value); }
    }

但我们不能将双重绑定到GridLength,我们应该添加转换。

public class DoubletoGridConvert : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        var n = (double) value;
        return new GridLength(n);
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

在我们写完之后,我们可以像下面那样制作页面。

      <Grid>
          <Grid.RowDefinitions>
              <RowDefinition Height="{x:Bind Rc,Mode=OneWay,Converter={StaticResource double}}"/>
              <RowDefinition Height="{x:Bind Lc,Mode=OneWay,Converter={StaticResource double}}"/>
          </Grid.RowDefinitions>
          <Grid Background="#FF565656"></Grid>
          <Grid Grid.Row="1" Background="#FFa2a2a2"></Grid>
      </Grid>
      <Button Margin="47,662,0,10" Content="set" Click="Button_OnClick"></Button>

点击按钮时我们会动画。

    private void Button_OnClick(object sender, RoutedEventArgs e)
    {
        this.Name = nameof(MainPage);
        var storyboard = new Storyboard();
        var animation = new DoubleAnimation();
        Storyboard.SetTargetName(animation, nameof(MainPage));
        Storyboard.SetTarget(animation, this);
        Storyboard.SetTargetProperty(animation,"Rc");
        animation.EnableDependentAnimation = true;
        animation.From = 100;
        animation.To = 200;
        animation.Duration = new Duration(TimeSpan.FromMilliseconds(500));
        storyboard.Children.Add(animation);
        storyboard.Begin();

        storyboard = new Storyboard();
        animation = new DoubleAnimation();
        Storyboard.SetTarget(animation, this);
        Storyboard.SetTargetName(animation,nameof(MainPage));
        Storyboard.SetTargetProperty(animation, nameof(Lc));
        animation.From = 500;
        animation.To = 150;
        animation.Duration = new Duration(TimeSpan.FromMilliseconds(500));
        animation.EnableDependentAnimation = true;
        storyboard.Children.Add(animation);

        storyboard.Begin();
    }

我认为它可以帮助你。