Silverlight 中 XAML、自定义属性和动画的非常奇怪的问题

发布于 2024-10-14 08:54:45 字数 2882 浏览 2 评论 0原文

我创建了一个自定义用户控件,该控件具有 Storyboard 类型的属性。类似于:

public class UC : UserControl
{
    public static readonly DependencyProperty AnimationProperty = DependencyProperty.Register(
        "Animation",
        typeof(Storyboard),
        typeof(UC),
        null);

    public Storyboard Animation
    {
        get { return (Storyboard)GetValue(AnimationProperty); }
        set { SetValue(AnimationProperty, value); }
    }

    public UC()
    {
        this.Loaded += new RoutedEventHandler(UC_Loaded);
    }

    private void UC_Loaded(object sender, RoutedEventArgs e)
    {
        if (this.Animation != null)
        {
            this.Animation.Begin();
        }
    }
}

在 XAML 中,我按如下方式使用它:

<loc:UC x:Name="uc" Opacity="0" >
    <TextBlock FontSize="50">Some text</TextBlock>
    <loc:UC.Animation>
        <Storyboard>
            <DoubleAnimation Storyboard.TargetName="uc" Storyboard.TargetProperty="Opacity" To="0.5" Duration="0:0:1" />
        </Storyboard>
    </loc:UC.Animation>
</loc:UC>

到目前为止一切顺利。

后来我决定除了故事板之外还需要另一个项目。因此,我更改了代码以接受包含故事板和另一条信息的自定义对象。类似于:

public class UC : UserControl
{
    public static readonly DependencyProperty AnimationProperty = DependencyProperty.Register(
        "Animation",
        typeof(AnimationHolder),
        typeof(UC),
        null);

    public AnimationHolder Animation
    {
        get { return (AnimationHolder)GetValue(AnimationProperty); }
        set { SetValue(AnimationProperty, value); }
    }

    public UC()
    {
        this.Loaded += new RoutedEventHandler(UC_Loaded);
    }

    private void UC_Loaded(object sender, RoutedEventArgs e)
    {
        if (this.Animation != null)
        {
            this.Animation.Animation.Begin();
        }
    }
}

public class AnimationHolder
{
    public Storyboard Animation
    {
        get;
        set;
    }

    public int OtherValue
    {
        get;
        set;
    }
}

并在 XAML 中使用它:

<loc:UC x:Name="uc" Opacity="0" >
    <TextBlock FontSize="50">Some text</TextBlock>
    <loc:UC.Animation>
        <loc:AnimationHolder OtherValue="20">
            <loc:AnimationHolder.Animation>
                <Storyboard>
                    <DoubleAnimation Storyboard.TargetName="uc" Storyboard.TargetProperty="Opacity" To="0.5" Duration="0:0:0" />
                </Storyboard>
            </loc:AnimationHolder.Animation>                            
        </loc:AnimationHolder>
    </loc:UC.Animation>
</loc:UC>

但是,现在当我尝试开始动画时,我收到 InvalidOperationException 并显示消息:“无法解析 TargetName uc。”

有人知道为什么吗?

我知道在这个例子中我可以通过不使用自定义对象而是使用另一个属性来解决这个问题。然而,这是我的场景的简化版本,它重点关注问题。在实际场景中我必须使用自定义对象。

I created a custom user control that has a property of type Storyboard. Something like:

public class UC : UserControl
{
    public static readonly DependencyProperty AnimationProperty = DependencyProperty.Register(
        "Animation",
        typeof(Storyboard),
        typeof(UC),
        null);

    public Storyboard Animation
    {
        get { return (Storyboard)GetValue(AnimationProperty); }
        set { SetValue(AnimationProperty, value); }
    }

    public UC()
    {
        this.Loaded += new RoutedEventHandler(UC_Loaded);
    }

    private void UC_Loaded(object sender, RoutedEventArgs e)
    {
        if (this.Animation != null)
        {
            this.Animation.Begin();
        }
    }
}

In XAML I used it as follows:

<loc:UC x:Name="uc" Opacity="0" >
    <TextBlock FontSize="50">Some text</TextBlock>
    <loc:UC.Animation>
        <Storyboard>
            <DoubleAnimation Storyboard.TargetName="uc" Storyboard.TargetProperty="Opacity" To="0.5" Duration="0:0:1" />
        </Storyboard>
    </loc:UC.Animation>
</loc:UC>

So far so good.

Later on I decided that I needed another item along with the storyboard. So I changed the code to accept a custom object that contains the storyboard and another piece of information. Something like:

public class UC : UserControl
{
    public static readonly DependencyProperty AnimationProperty = DependencyProperty.Register(
        "Animation",
        typeof(AnimationHolder),
        typeof(UC),
        null);

    public AnimationHolder Animation
    {
        get { return (AnimationHolder)GetValue(AnimationProperty); }
        set { SetValue(AnimationProperty, value); }
    }

    public UC()
    {
        this.Loaded += new RoutedEventHandler(UC_Loaded);
    }

    private void UC_Loaded(object sender, RoutedEventArgs e)
    {
        if (this.Animation != null)
        {
            this.Animation.Animation.Begin();
        }
    }
}

public class AnimationHolder
{
    public Storyboard Animation
    {
        get;
        set;
    }

    public int OtherValue
    {
        get;
        set;
    }
}

And used it in XAML:

<loc:UC x:Name="uc" Opacity="0" >
    <TextBlock FontSize="50">Some text</TextBlock>
    <loc:UC.Animation>
        <loc:AnimationHolder OtherValue="20">
            <loc:AnimationHolder.Animation>
                <Storyboard>
                    <DoubleAnimation Storyboard.TargetName="uc" Storyboard.TargetProperty="Opacity" To="0.5" Duration="0:0:0" />
                </Storyboard>
            </loc:AnimationHolder.Animation>                            
        </loc:AnimationHolder>
    </loc:UC.Animation>
</loc:UC>

However, now when I try to begin the animation I get an InvalidOperationException with the message: "Cannot resolve TargetName uc."

Anyone has an idea why?

I know that in this example I can work around the problem by not using a custom object, and using another property instead. However this is a simplified version of my scenario, which focuses at the problem. In the real scenario I must use a custom object.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

陌生 2024-10-21 08:54:45

使用新方法需要完成两件事:

  • AnimationHolder 类中,将 Animation 属性设置为依赖属性,就像以前一样。
  • DependencyObject 派生 AnimationHolder 类。这是必要的,以便您可以将 Animation 设为依赖属性。请记住,只有从 DependencyObject 派生的类才能定义依赖属性!

我想只要你做到了这两点,问题就迎刃而解了!

Two things need to be done with your new approach:

  • In AnimationHolder class, make Animation property a dependency property, just like it previously was.
  • Derive AnimationHolder class from DependencyObject. This is necessary so that you can make Animation a dependency property. Please remember that only classes deriving from DependencyObject can define dependency properties!

I think once you do these two things, it'll solve your problem!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文