C# 当移动一个简单的矩形时,wpf中有3种不同结果的模拟方法
我对wpf应用程序中的任务有一个奇怪的问题。我创建了一个简单的程序,并在其上放置了一个名为“RectObj”的矩形,该矩形带有一个调用3种方法之一的按钮。我正试图用C#代码在屏幕上平滑地滑动它。我不想使用动画,我真的想知道为什么下面的代码在每种情况下都会这样做,以及如何在没有动画的情况下修复它C# 当移动一个简单的矩形时,wpf中有3种不同结果的模拟方法,c#,wpf,C#,Wpf,我对wpf应用程序中的任务有一个奇怪的问题。我创建了一个简单的程序,并在其上放置了一个名为“RectObj”的矩形,该矩形带有一个调用3种方法之一的按钮。我正试图用C#代码在屏幕上平滑地滑动它。我不想使用动画,我真的想知道为什么下面的代码在每种情况下都会这样做,以及如何在没有动画的情况下修复它 // has a delay in the initial few moments without moving, then jumps to it's position and thereafter r
// has a delay in the initial few moments without moving, then jumps to it's position and thereafter runs perfectly smooth even after another button press
public void test()
{
Task.Run(() =>
{
for (int x = 0; x < 100; x++)
{
this.Dispatcher.Invoke((() =>
{
var margin = RectObj.Margin;
margin.Left = testValue++;
RectObj.Margin = margin;
}));
Thread.Sleep(10);
}
});
}
// runs, but jagged movements/refreshing
public void test2()
{
Task.Run(() =>
{
for (int x = 0; x < 100; x++)
{
this.Dispatcher.Invoke((() =>
{
var margin = RectObj.Margin;
margin.Left = testValue++;
RectObj.Margin = margin;
Thread.Sleep(10);
}));
}
});
}
// does not update display until task is completed
public void test3()
{
Task.Run(() =>
{
this.Dispatcher.Invoke((() =>
{
for (int x = 0; x < 100; x++)
{
var margin = RectObj.Margin;
margin.Left = testValue++;
RectObj.Margin = margin;
Thread.Sleep(10);
}
}));
});
}
//在最初的几分钟内有一个延迟,但没有移动,然后跳到它的位置,然后即使再按一次按钮,运行也非常平稳
公开无效测试()
{
Task.Run(()=>
{
对于(int x=0;x<100;x++)
{
this.Dispatcher.Invoke((()=>
{
var保证金=矩形保证金;
margin.Left=testValue++;
矩形边缘=边缘;
}));
睡眠(10);
}
});
}
//跑步,但动作参差不齐/令人耳目一新
公共无效测试2()
{
Task.Run(()=>
{
对于(int x=0;x<100;x++)
{
this.Dispatcher.Invoke((()=>
{
var保证金=矩形保证金;
margin.Left=testValue++;
矩形边缘=边缘;
睡眠(10);
}));
}
});
}
//在任务完成之前不更新显示
公共无效测试3()
{
Task.Run(()=>
{
this.Dispatcher.Invoke((()=>
{
对于(int x=0;x<100;x++)
{
var保证金=矩形保证金;
margin.Left=testValue++;
矩形边缘=边缘;
睡眠(10);
}
}));
});
}
第一种情况,我真的不知道你为什么第一次耽搁。我猜它正在进行某种初始化(否则每次按下按钮都会有延迟),但我不确定具体是什么
对于案例二和案例三,您必须了解两件事:
Dispatcher.Invoke中的任何内容都将由UI线程执行
- 当调度程序回调正在运行时,UI不会刷新。长话短说,UI线程执行一个无限循环,在刷新UI(即,根据控件的值绘制屏幕上应该显示的内容)和执行与调度程序一起排队的任何回调之间交替进行
- 在第二种情况下,UI线程执行
。当它处于睡眠状态时,它无法刷新UI线程.Sleep
- 在第三种情况下,您永远不会退出dispatcher,UI线程没有机会重新绘制屏幕
至于知道如何修复它。。。当然,最好的方法是使用动画。如果您确实不想,至少使用
TranslateTransform
移动控件,而不是更改边距。使用TranslateTransform
(指定给控件的RenderTransform
属性)只会更改控件的视觉外观(而不是实际位置),因此速度很快。更改边距会迫使WPF重新计算部分布局,这需要CPU。嘿,谢谢。现在对案例2和3有意义了。我现在了解了调度器的工作原理。而translateTransform似乎解决了初始滞后的问题。谢谢你的帮助