0

我在 xaml 页面上尝试了一个简单的重复动画,如下所示:

<StackPanel Canvas.Left="1" Canvas.Top="1">
    <StackPanel.Triggers>
        <EventTrigger RoutedEvent="Loaded">
            <BeginStoryboard>
                <Storyboard x:Name="sb_PathGeometry" RepeatBehavior="Forever">
                     <PointAnimationUsingPath Storyboard.TargetName="PathGeometry"  
                          Storyboard.TargetProperty="Center"  
                          Duration="0:0:1">
                          <PointAnimationUsingPath.PathGeometry>
                              <PathGeometry Figures="M 10,0 L 10,-182 L -199,-182" />
                          </PointAnimationUsingPath.PathGeometry>
                     </PointAnimationUsingPath>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </StackPanel.Triggers>
</StackPanel>

然后,我计划使用下面的代码控制空闲页面(从另一个站点查找):

using System.Windows.Threading;
using System.Windows.Interop;

namespace DS
{
    public partial class MontagePage : Page
    {
        private EventHandler handler;

        public MontagePage()
        {
            InitializeComponent();

            handler = delegate
            {
                DispatcherTimer timer = new DispatcherTimer();
                timer.Interval = TimeSpan.FromSeconds(4);
                timer.Tick += delegate
                {
                    if (timer != null)
                    {
                        timer.Stop();
                        timer = null;
                        System.Windows.Interop.ComponentDispatcher.ThreadIdle -= handler;
                        ComponentDispatcher_ThreadIdle();
                        System.Windows.Interop.ComponentDispatcher.ThreadIdle += handler;
                    }
                };
                timer.Start();

                //System.Windows.Interop.ComponentDispatcher.ThreadIdle -= handler;
                Dispatcher.CurrentDispatcher.Hooks.OperationPosted += delegate
                {
                    if (timer != null)
                    {
                        timer.Stop();
                        timer = null;
                    }
                };
            };

            ComponentDispatcher.ThreadIdle += handler;
        }

        void ComponentDispatcher_ThreadIdle()
        {
            //Go to IdlePage.xaml
            IdlePage idlepage = new IdlePage();
            this.NavigationService.Navigate(idlepage);
        }
    }
}

我可以总结的问题是:

  1. 由于该动画一直在运行,因此空闲控件不会触发。如何让它发挥作用?
4

2 回答 2

0

* 第1部分 *

每次进入委托块时,您都在创建新的计时器。

来自 MSDN 的注释:

将 Enabled 设置为 true 与调用 Start 相同,将 Enabled 设置为 false 与调用 Stop 相同。

所以第一步我建议至少将您的代码重构为仅启用重置

//sorry I changed your delegates to lambda's for my convenience (personal pref), but the point stands
public MontagePage()
    {
        InitializeComponent();
        timer.Interval = TimeSpan.FromSeconds(4);

        handler = (s1,a1) =>
        {
            timer.Tick += (s2, a2) =>
            {
                if (timer.IsEnabled)
                {
                    timer.IsEnabled = false;
                    ComponentDispatcher.ThreadIdle -= handler;
                    ComponentDispatcher_ThreadIdle();
                    ComponentDispatcher.ThreadIdle += handler;
                }
            };
            timer.Start();

            Dispatcher.CurrentDispatcher.Hooks.OperationPosted 
                += (s, a)
                    =>
                    {
                        if (timer.IsEnabled)
                            timer.IsEnabled = false;
                    };
        };

        ComponentDispatcher.ThreadIdle += handler;
    }

* 第2部分:*

删除 RepeatBehavior="Forever",您的代码将根据计时器开始触发。

于 2012-04-25T15:27:26.927 回答
0

Putting this in a different answer, because the approach is different. Change your timer to system timer to leverage on timer.elapsed, where you can spawn an action on a different thread.

 public MontagePage()
    {
        InitializeComponent();

        var timer = new System.Timers.Timer {Interval = 4000, Enabled = true};
        timer.Elapsed += (s, a) => Task.Factory.StartNew(ComponentDispatcher_ThreadIdle);

        .....

this will work without you changing your XAML.

于 2012-04-25T15:57:55.087 回答