[Silverlight]Element is already the child of another element与Cannot resolve TargetProperty解决方案

来源:互联网 发布:php初学者基础知识 编辑:程序博客网 时间:2024/06/05 16:48

本文将简单分析几个Silverlight程序开发中经常遇到的问题的解决方案。

1.Element is already the child of another element

从字面意思,可以理解为:元素已经是另一个元素的子元素。在Silverlight中,每一个Element均只能从属于一个父元素;如果重复将一个元素分配给不同的父元素则会出现这样的异常。

这种错误多在通过代码添加子元素等情况中出现,而且对于初学者甚至很难想明白为什么会出错,比如在我上一篇文章中提到的动画:

每一个动画的TimeLine都通过关键帧动画来实现,其中有一段代码为:

 DoubleAnimationUsingKeyFrames xTimeLine = new DoubleAnimationUsingKeyFrames();
            var xKeyFrames = xTimeLine.KeyFrames;
            xKeyFrames.Add(this.GetKeyFrame(0, 0));
            xKeyFrames.Add(this.GetKeyFrame(2.5, 30));
            xKeyFrames.Add(this.GetKeyFrame(5.0, 90));

如果将这段代码修改为:

DoubleAnimationUsingKeyFrames xTimeLine = new DoubleAnimationUsingKeyFrames();

            var xKeyFrames = new DoubleKeyFrameCollection();
            xKeyFrames.Add(this.GetKeyFrame(0, 0));
            xKeyFrames.Add(this.GetKeyFrame(2.5, 30));
            xKeyFrames.Add(this.GetKeyFrame(5.0, 90));
            foreach (var frame in xKeyFrames)
            {
                xTimeLine.KeyFrames.Add(frame);
            }

则会在 xTimeLine.KeyFrames.Add(frame);行抛出这样的异常:Element is already the child of another element。

这段代码,在我们的以往经验中,大家可能不会觉得有什么问题,而这里之所以会出现异常的原因则是因为DoubleKeyFrameCollection不是一个单纯的集合了,它不仅实现了集合的一些接口,还继承于DependencyObject,当我们向其中添加DoubleKeyFrame(也属于DependencyObject的后代)的时候,实际上也将其parent设置为了这个集合对象;于是当我们再试图将其添加到其他元素子元素中时,就抛出了异常。

2.Cannot resolve TargetProperty

这类异常的抛出往往是因为我们没有设置相应的Proerty:在XAML中即为没有添加相应的属性元素,在CODE中即为没有对相应的属性实例化。

比如如果去掉前一篇文章中的ball.RenderTransform = new CompositeTransform();这行代码;则会在Storyboard.SetTargetProperty(xTimeLine, new PropertyPath("(UIElement.RenderTransform).(CompositeTransform.TranslateX)"));抛出这样的异常:Cannot resolve TargetProperty (UIElement.RenderTransform).(CompositeTransform.TranslateY) on specified object.

解决方法就是实例化RenderTransform这个属性:ball.RenderTransform = new CompositeTransform();

如果是使用XAML中的Stroryboard抛出了这个异常,那么相应的解决方案即为添加相应的元素,比如上面CODE的等价XAML是:

 <Canvas.RenderTransform>
                <CompositeTransform/>
 </Canvas.RenderTransform>

注意:需要将Canvas修改为你设置动画的Element类型。

3.与WPF的区别

Silverlight的“值域”与“定义域”均小于WPF,因此在WPF中有的功能与特性,在Silverlight中并不一定有,比如DoubleAnimationUsingPath在Silverlight并无与之对应的类。我们在开发的时候一定要清楚不同框架之间的区别与联系,这样才可能尽量避免不必要的错误出现。

原创粉丝点击