5

Metro XAML アプリでいくつかのストーリーボードをいじっています。Storyboardインコードを作成する必要があります。Storyboard.TargetPropertyに設定したいCompositeTransform.Rotation

無理そうです…

XAML のストーリーボードは次のようになります。

<Storyboard>
    <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" Storyboard.TargetName="grid">
        <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="60"/
    </DoubleAnimationUsingKeyFrames>
</Storyboard>

似たようなものを作りたいと思っています。
重要:このストーリーボードを正確に再現しようとしているわけではありません。私は custom のコードの中にいてContentControlthisアニメーションControlの対象となる「グリッド」がありません。ターゲットは、CompositeTransform以前に設定されたコントロール自体です。

これまでの私のコードは次のようなものです:

var turnSB = new Storyboard();

var doubleAnim = new DoubleAnimationUsingKeyFrames();
doubleAnim.KeyFrames.Add(new EasingDoubleKeyFrame() { KeyTime = TimeSpan.FromMilliseconds(0), Value = currentAngle });
doubleAnim.KeyFrames.Add(new EasingDoubleKeyFrame() { KeyTime = TimeSpan.FromMilliseconds(500), Value = targetAngle });

turnSB.Children.Add(doubleAnim);

Storyboard.SetTarget(doubleAnim, this.RenderTransform);
Storyboard.SetTargetProperty(doubleAnim, "(CompositeTransform.Rotation)");

turnSB.Begin();

Begin メソッドに到達するとすぐに、(CompositeTransform.Rotation) を解決できないという例外が発生します。そのため、プロパティ パスが正しく取得されていないと推測しています。さまざまなバリエーションを試しましたが、PropertyPaths によると、これが正しいはずですよね? :S

これが解決できない問題である場合は、回避策についての提案をお待ちしています...

編集:

今のところ問題は解決したと思います。しかし、いくつかの興味深い発見があります...

UserControl を作成すれば、実質的に何でもできます。すべてが機能し、Storyboard.Target プロパティを設定でき、アニメーションが正しく再生されます。

ただし、カスタム コントロールを使用するか、別のコントロール (ContentControl など) から継承する場合、コードから Storyboard を開始できない場合があります。

例: ストーリーボード (XAML で定義) を作成して Rotation (またはその変換プロパティ) をアニメーション化し、コードから開始しようとすると、上記の例外が発生します。しかし、不透明度などの単純なプロパティをアニメーション化すると、正常に機能します。
(私は UserControl でも同じことをしましたが、うまくいきました。)

誰かがこれを説明できますか?

4

3 に答える 3

4

MSDNのドキュメントから、文字列パス全体を設定する必要があるようです。したがって、xamlで記述されているアニメーションの場合、TargetPropertyをそのように設定する必要があります

Storyboard.SetTargetProperty(doubleAnim, "(UIElement.RenderTransform).(CompositeTransform.Rotation)");

更新:ストーリーボードの子としてタイムラインを追加するこのブログ投稿を見つけました。次のことを試してください。

Storyboard.SetTarget(doubleAnim, this.RenderTransform);
Storyboard.SetTargetProperty(doubleAnim, "Rotation"); // maybe "CompositeTransform.Rotation"
storyboard.Children.Add(doubleAnim);
于 2012-08-14T16:53:55.137 に答える
4

RenderTransformこのエラーが発生する理由は、カスタム コントロールのプロパティをインスタンス化していないためだと思います。

public class CustomControl2 : Control
{
    public CustomControl2()
    {
        this.DefaultStyleKey = typeof(CustomControl2);
    }

    protected override void OnApplyTemplate()
    {
        base.OnApplyTemplate(); 
    }

    public void RunAnimation()
    {
        //this.RenderTransform = new CompositeTransform();
        this.Background = new SolidColorBrush(Color.FromArgb(0xFF, 0x33, 0xC8, 0x9C));

        var turnSB = new Storyboard();

        var doubleAnim = new DoubleAnimationUsingKeyFrames();
        doubleAnim.KeyFrames.Add(new EasingDoubleKeyFrame() { KeyTime = TimeSpan.FromMilliseconds(0), Value = 10 });
        doubleAnim.KeyFrames.Add(new EasingDoubleKeyFrame() { KeyTime = TimeSpan.FromMilliseconds(500), Value = 30 });

        turnSB.Children.Add(doubleAnim);

        Storyboard.SetTarget(doubleAnim, this.RenderTransform);
        Storyboard.SetTargetProperty(doubleAnim, "(CompositeTransform.Rotation)");

        turnSB.Begin();
    }
}

上記のコードで、 method の下の最初の行をコメントアウトするRunAnimationと、同じエラーが発生することに注意してください。

次に、メイン ページにこのコントロールを作成Buttonし、アニメーションを開始する も作成しました。

private void Button_Click_1(object sender, RoutedEventArgs e)
{
    this.MyControl.RunAnimation();
}

上記のコードをテストしたところ、問題なく動作しました。

于 2013-01-18T06:01:27.703 に答える
1

解決しました

問題は、使用している要素へのパスにあります。親クラスから派生して、プロパティ自体に拡張する必要があります。私はそれを自分のコントロールで動作させているので、コピーして貼り付けることができる小さな例を作成しました(テストされていないコード):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;

namespace CustomControls
{
    /// <summary>
    /// Author: Frank Wolferink
    /// Note: example is untested and comes as is. I hope it save's you the time i lost figering this out
    /// </summary>
    public class CustomControl : Control
    {

        private Storyboard _compositeTransformExampleStoryBoard;

        private const string TRANSLATE_X_TARGET = "Control.RenderTransform.CompositeTransform.TranslateX";
        private const string TRANSLATE_Y_TARGET = "Control.RenderTransform.CompositeTransform.TranslateY";
        private const string TRANSLATE_ROTATE_TARGET = "Control.RenderTransform.CompositeTransform.Rotation";


        public CustomControl()
        {
            this.RenderTransform = new CompositeTransform();

            TimeSpan duration = new TimeSpan(0,0,0,0,500);
            double translateX = 10;
            double translateY = 10;
            double rotation = 40;

            _compositeTransformExampleStoryBoard = BuildStoryboard(duration, translateX, translateY, rotation);

            this.Loaded += CustomControl_Loaded;
        }

        void CustomControl_Loaded(object sender, RoutedEventArgs e)
        {
            _compositeTransformExampleStoryBoard.Begin();
        }


        private Storyboard BuildStoryboard(TimeSpan animationDuration, double transistionValueX, double transistionValueY, double rotation)
        {
            Storyboard storyboard = new Storyboard();

            if (transistionValueX != 0)
                CreateAnimation(storyboard, transistionValueX, animationDuration, TRANSLATE_X_TARGET);

            if (transistionValueY != 0)
                CreateAnimation(storyboard, transistionValueY, animationDuration, TRANSLATE_Y_TARGET);

            if (rotation != 0)
                CreateAnimation(storyboard, rotation, animationDuration, TRANSLATE_ROTATE_TARGET);


            return storyboard;
        }

        private void CreateAnimation(Storyboard storyboard, double transistionValue, TimeSpan animationDuration, string targetProperty)
        {
            DoubleAnimation da = CreateDoubleAnimation(transistionValue, animationDuration);
            storyboard.Children.Add(da);
            Storyboard.SetTarget(da, this);
            Storyboard.SetTargetProperty(da, targetProperty);
        }

        private DoubleAnimation CreateDoubleAnimation(double transistionValue, TimeSpan duration)
        {
            return new DoubleAnimation()
            {
                Duration = duration,
                To = transistionValue
            };
        }

    }
}

于 2013-01-30T13:57:27.157 に答える