在 WPF 中按下键时移动形状
本文关键字:移动 WPF | 更新日期: 2023-09-27 18:37:22
我想在用户按住某个键时移动窗口中的形状。我是新手,所以我尝试了这种方法,但我无法改变圆圈。从我的新线程重新转换,因为它属于不同的线程。应该怎么做?
public partial class MainWindow : Window
{
private Matrix transformationMatrix = Matrix.Identity;
private Thread myThread = null;
private bool isGoing = false;
public MainWindow()
{
InitializeComponent();
}
private void Window_KeyDown(object sender, KeyEventArgs e)
{
isGoing = true;
myThread = new Thread(HandleMyThread);
myThread.Start();
}
private void Window_KeyUp(object sender, KeyEventArgs e)
{
isGoing = false;
}
private void HandleMyThread(object obj)
{
while(isGoing)
{
transformationMatrix.Translate(10, 0);
circle.RenderTransform = new MatrixTransform(transformationMatrix);
Thread.Sleep(50);
}
}
}
在 WPF 中,您希望将 System.Windows.Threading.DispatcherTimer
类用于 UI 线程安全计时器。
下面是一个示例:
public partial class MainWindow : Window
{
private DispatcherTimer _timer;
public MainWindow()
{
InitializeComponent();
}
protected override void OnContentRendered(EventArgs e)
{
base.OnContentRendered(e);
_timer = new DispatcherTimer();
_timer.Interval = TimeSpan.FromMilliseconds(50);
_timer.Tick += timer_Tick;
}
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
_timer.Start();
}
protected override void OnKeyUp(KeyEventArgs e)
{
base.OnKeyUp(e);
_timer.Stop();
}
private void timer_Tick(object sender, EventArgs e)
{
transform.X += 2;
transform.Y += 2;
}
}
您可能只需使用Invoke
就可以侥幸逃脱......但是有更好的方法来做你想做的事情。
首先,每次处理KeyDown
时创建一个线程是低效的......并可能导致问题...因为创建和安排Thread
可能需要一段时间......因此,您的"事物"移动会延迟。
此外,您可能会因为存在多个线程而陷入混乱。例如,假设有人反复按下并释放键......在这种情况下,"旧"线程仍有可能继续运行......因为isGoing
旗帜是真的。换句话说,同步性很差。
private void HandleMyThread(object obj)
{
Action action = new Action( ()=>
{
transformationMatrix.Translate(10, 0);
circle.RenderTransform = new MatrixTransform(transformationMatrix);
};
while(isGoing)
{
this.Dispatcher.Invoke(DispatcherPriority.Normal, action);
Thread.Sleep(50);
}
}