自定义控件中的故事板

时间:2010-10-29 12:18:08

标签: silverlight windows-phone-7 custom-controls storyboard

我在Silverlight中有一个usercontrol,我正在尝试转换为自定义控件。 用户控件正在运行。 自定义控件正在工作但是它的故事板不起作用。

控件是:

public class MyControl : Control
{
    public MyControl()
    {
        DefaultStyleKey = typeof(MyControl);
    }

    public static readonly DependencyProperty IsStartingProperty = DependencyProperty.Register("IsStarting", typeof(bool), typeof(MyControl), new PropertyMetadata(new PropertyChangedCallback(OnIsStartingChanged)));

    private static void OnIsStartingChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        MyControl control = obj as MyControl;
        if (control != null && control._layoutRoot != null && control._storyboard != null)
        {
            if ((bool)e.NewValue)
            {
                control._layoutRoot.Visibility = Visibility.Visible;
                control._storyboard.Begin();
            }
            else
            {
                control._layoutRoot.Visibility = Visibility.Collapsed;
                control._storyboard.Stop();
            }
        }
    }

    private Canvas _layoutRoot;
    private Storyboard _storyboard;

    public override void OnApplyTemplate()
    {
        _layoutRoot = GetTemplateChild("LayoutRoot") as Canvas;
        _storyboard = GetTemplateChild("IndicatorStoryboard") as Storyboard;
        base.OnApplyTemplate();
    }

    public bool IsStarting
    {
        get { return (bool)GetValue(IsStartingProperty); }
        set { SetValue(IsStartingProperty, value); }
    }
}

在调试时,control._storyboard.Begin();上没有错误,但我看不到动画......

有人有想法吗?如何使用故事板?

提前感谢您提供任何帮助

编辑:提供完整的源样本:http://vpclip.virtua-peanuts.net/WindowsPhoneApplication1.zip

2 个答案:

答案 0 :(得分:0)

这是我的头脑,但如果移动“base.OnApplyTemplate();会发生什么? “作为OnApplyTemplate()函数的第一行?

   public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        _layoutRoot = GetTemplateChild("LayoutRoot") as Canvas;
        _storyboard = GetTemplateChild("IndicatorStoryboard") as Storyboard;
    }

这有帮助吗?

答案 1 :(得分:0)

如果在按钮单击处理程序中将IsBusy设置为true,您将看到动画确实有效。问题是你在加载之前将它设置为true,因此_layoutRoot和_storyboard为null并且动画永远不会开始。

public class CustomBusyControl : Control
{
    public CustomBusyControl()
    {
        DefaultStyleKey = typeof(CustomBusyControl);
        Loaded += (s,e) => ToggleBusy(this);
    }

    public static readonly DependencyProperty IsBusyProperty = DependencyProperty.Register("IsBusy", typeof(bool), typeof(CustomBusyControl), new PropertyMetadata(new PropertyChangedCallback(OnIsBusyChanged)));

    private static void OnIsBusyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        ToggleBusy(obj as CustomBusyControl);
    }

    private static void ToggleBusy(CustomBusyControl control)
    {
        if (control != null && control._layoutRoot != null && control._storyboard != null)
        {
            if ((bool)control.IsBusy)
            {
                control._layoutRoot.Visibility = Visibility.Visible;
                control._storyboard.Begin();
            }
            else
            {
                control._layoutRoot.Visibility = Visibility.Collapsed;
                control._storyboard.Stop();
            }
        }
    }

    private Canvas _layoutRoot;
    private Storyboard _storyboard;

    public override void OnApplyTemplate()
    {
        _layoutRoot = GetTemplateChild("LayoutRoot") as Canvas;
        Debug.Assert(_layoutRoot != null, "LayoutRoot is null");
        _storyboard = GetTemplateChild("IndicatorStoryboard") as Storyboard;
        base.OnApplyTemplate();
    }

    public bool IsBusy
    {
        get { return (bool)GetValue(IsBusyProperty); }
        set { SetValue(IsBusyProperty, value); }
    }
}