Silverlight: Probleme mit erstellten Storyboards im Managed Code

magic_x

Grünschnabel
Hallo alle zusammen,

ich habe folgendes Problem.
Ich habe mir eine Klasse gebastelt, in der ich zwei Storyboards erstelle.
Mit den einen fliegen alle Elemente die ich zum Storyboard eingefügt rein.
Mit dem anderen fliegen alle Elemente die ich zum Storyboard eingefügt raus.

So nun zu meinem Problem, wenn ich nun diese Storyboard's ausführe funktionieren
diese beim ersten mal wie sie sollen. führe ich diese aber zum zweiten mal aus gibt es eine Fehlermeldung:
Cannot resolve TargetProperty (UIElement.RenderTransform).(TranslateTransform.X) on specified object.


Wenn jemand dieses Problem mal selber testen möchte, kann er mein Test Programm hier downloaden.

So kommen wir mal zu den Code Flying.cs:
Code:
namespace FlyTestSolution
{
    public class Flying
    {
        private Storyboard flyIn = new Storyboard();
        private Storyboard flyOut = new Storyboard();

        Panel parentUI = null;

        public Flying(Panel parent, string name)
        {
            this.parentUI = parent;
            this.parentUI.Resources.Add("FlyIn" + name, flyIn);
            this.parentUI.Resources.Add("FlyOut" + name, flyOut);
        }

        public void addUIElement(FrameworkElement elm, String flyCourse)
        {
            DoubleAnimationUsingKeyFrames dIn = new DoubleAnimationUsingKeyFrames();
            dIn.BeginTime = new TimeSpan();

            DoubleAnimationUsingKeyFrames dOut = new DoubleAnimationUsingKeyFrames();
            dOut.BeginTime = new TimeSpan();

            Double width = this.parentUI.ActualWidth;

            if (flyCourse == "right")
            {
                Double rightStart = 0;
                if (width < 996)
                    rightStart = 996;
                else
                    rightStart = width;

                createSplineDoubleKeyFrame(dIn, 0, rightStart);
                createSplineDoubleKeyFrame(dIn, 0.7, -20);
                createSplineDoubleKeyFrame(dIn, 0.75, 20);
                createSplineDoubleKeyFrame(dIn, 0.8, -12);
                createSplineDoubleKeyFrame(dIn, 0.85, 12);
                createSplineDoubleKeyFrame(dIn, 0.9, -4);
                createSplineDoubleKeyFrame(dIn, 0.95, 4);
                createSplineDoubleKeyFrame(dIn, 1, 0);

                createSplineDoubleKeyFrame(dOut, 0, 0);
                createSplineDoubleKeyFrame(dOut, 1, rightStart);
            }
            else
            {
                Double leftStart = 0;
                if (width < 996)
                    leftStart = 996 / 2 + elm.ActualWidth;
                else
                    leftStart = (width - 996) / 2 + elm.ActualWidth;

                Double left = -1 * leftStart;

                createSplineDoubleKeyFrame(dIn, 0, left);
                createSplineDoubleKeyFrame(dIn, 0.7, 20);
                createSplineDoubleKeyFrame(dIn, 0.75, -20);
                createSplineDoubleKeyFrame(dIn, 0.8, 12);
                createSplineDoubleKeyFrame(dIn, 0.85, -12);
                createSplineDoubleKeyFrame(dIn, 0.9, 4);
                createSplineDoubleKeyFrame(dIn, 0.95, -4);
                createSplineDoubleKeyFrame(dIn, 1, 0);

                createSplineDoubleKeyFrame(dOut, 0, 0);
                createSplineDoubleKeyFrame(dOut, 1, left);
            }

            elm.RenderTransform = new TranslateTransform();

            Storyboard.SetTarget(dIn, elm);
            Storyboard.SetTargetProperty(dIn, new PropertyPath("(FrameworkElement.RenderTransform).(TranslateTransform.X)"));
            flyIn.Children.Add(dIn);

            Storyboard.SetTarget(dOut, elm);
            Storyboard.SetTargetProperty(dOut, new PropertyPath("(FrameworkElement.RenderTransform).(TranslateTransform.X)"));
            flyOut.Children.Add(dOut);

        }

        private void createSplineDoubleKeyFrame(DoubleAnimationUsingKeyFrames daukf, Double time, double value)
        {
            SplineDoubleKeyFrame sdkf = new SplineDoubleKeyFrame();
            sdkf.KeyTime = TimeSpan.FromSeconds(time);
            sdkf.Value = value;
            daukf.KeyFrames.Add(sdkf);
        }

        public void startFlyIn()
        {
            try
            {
                flyIn.Begin();
                flyIn.Completed += new EventHandler(flying_Completed);
            }
            catch (Exception e)
            {
                Debug.WriteLine("Fehlermeldung flyIn: " + e.Message);
            }
        }

        public void startFlyOut()
        {
            try
            {
                flyOut.Begin();
                flyOut.Completed += new EventHandler(flying_Completed);
            }
            catch (Exception e)
            {
                Debug.WriteLine("Fehlermeldung flyOut: " + e.Message);
            }
        }

        void flying_Completed(object sender, EventArgs e)
        {
            if (CompletedHandler != null)
                CompletedHandler(this, e);
        }

        public delegate void LoadedEventHandler(object sender, EventArgs args);
        public event LoadedEventHandler CompletedHandler;
    }
}

Der Code zu Page.xaml:
Code:
<UserControl x:Class="FlyTestSolution.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="Auto" Height="Auto" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignWidth="862" d:DesignHeight="382">
    <Grid x:Name="LayoutRoot" Background="White">

    	<Rectangle Height="100" HorizontalAlignment="Left" Margin="201.5,98.5,0,162.5" x:Name="rec1" VerticalAlignment="Top" Width="200" Fill="#FFC62525" Stroke="#FF000000" d:LayoutOverrides="Width, Height"/>
    	<Rectangle Height="105" HorizontalAlignment="Right" Margin="0,113,91,0" x:Name="rec2" VerticalAlignment="Top" Width="243" Fill="#FF1774D2" Stroke="#FF000000" d:LayoutOverrides="VerticalAlignment"/>
    	<Button Height="38" HorizontalAlignment="Left" Margin="185,0,0,56" VerticalAlignment="Bottom" Width="107" Content="FlyIn" x:Name="_buttonFlyIn"/>
    	<Button Height="38" HorizontalAlignment="Right" Margin="0,0,292,56" VerticalAlignment="Bottom" Width="125" Content="FlyOut" x:Name="_buttonFlyOut"/>

    </Grid>
</UserControl>

Und zuletzt der Code zu Page.xaml.cs:
Code:
namespace FlyTestSolution
{
    public partial class Page : UserControl
    {
        Flying _fly = null;

        public Page()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(Page_Loaded);
        }

        void Page_Loaded(object sender, RoutedEventArgs e)
        {
            _fly = new Flying(LayoutRoot,"Fly");
            _fly.addUIElement(rec1, "left");
            _fly.addUIElement(rec2, "right");
            _buttonFlyIn.Click += new RoutedEventHandler(_buttonFlyIn_Click);
            _buttonFlyOut.Click += new RoutedEventHandler(_buttonFlyOut_Click);
        }

        void _buttonFlyOut_Click(object sender, RoutedEventArgs e)
        {
            _fly.startFlyOut();
        }

        void _buttonFlyIn_Click(object sender, RoutedEventArgs e)
        {
            _fly.startFlyIn();
        }

       
    }
}

Ihr würdet mir sehr helfen, ich sitze schon mehr als zwei Tage an diesem Problem, kann es aber einfach nicht lösen.

Danke schon mal im voraus

Peter
 
Hi Leute,

hab auf dem Silverlight Forum eine Antwort von einem Entwickler zu diesem Problem bekommen:

Hello, this is a known issue. For some properties, SetTarget will only work for the first times. We're investigating the cause to this problem. In the meanwhile, can you use SetTargetName instead? You can use SetValue(FrameworkElement.NameProperty, "yourName") to give your object a name. Or, you can call SetTarget each time before you begin the storyboard.

Also ich habe das Problem dahingehend gelöst, das ich vor jedem start eines Storyboards die einzelnen DoubleAnimationUsingKeyFrames und die dazugehörigen Kinder neu erstelle.

Gruß

Peter
 
Zurück