我在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);
}
}
}
我可以总结的问题是:
答案 0 :(得分: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” 并且您的代码将根据计时器开始触发。
答案 1 :(得分:0)
将其置于不同的答案中,因为方法不同。将您的计时器更改为系统计时器以利用timer.elapsed,您可以在其他线程上生成操作。
public MontagePage()
{
InitializeComponent();
var timer = new System.Timers.Timer {Interval = 4000, Enabled = true};
timer.Elapsed += (s, a) => Task.Factory.StartNew(ComponentDispatcher_ThreadIdle);
.....
无需更改XAML即可使用。