0

我想在用户按住一个键时在窗口中移动一个形状。我是新手,所以我尝试了这种方法,但我无法从我的新线程中更改 circle.RederTransform,因为它属于不同的线程。应该怎么做?

    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);
            }
        }

    }
4

2 回答 2

1

在 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;
    }
}
于 2013-10-28T19:19:15.573 回答
0

您可能只需使用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);
    }
}
于 2013-10-28T19:22:03.673 回答