2

这是 WPF 中的一个小布朗运动演示:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Threading;

namespace WpfBrownianMotion
{
    static class MiscUtils
    {
        public static double Clamp(this double n, int low, double high)
        {
            return Math.Min(Math.Max(n, low), high);
        }
    }

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            Width = 500;
            Height = 500;

            var canvas = new Canvas();

            Content = canvas;

            var transform = new TranslateTransform(250, 250);

            var circle = new Ellipse()
            {
                Width = 25,
                Height = 25,
                Fill = Brushes.PowderBlue,
                RenderTransform = transform
            };

            canvas.Children.Add(circle);

            var random = new Random();

            var thread =
                new Thread(
                    () =>
                    {
                        while (true)
                        {
                            Dispatcher.Invoke(
                                DispatcherPriority.Normal,
                                (ThreadStart)delegate()
                                {
                                    transform.X += -1 + random.Next(3);
                                    transform.Y += -1 + random.Next(3);

                                    transform.X = transform.X.Clamp(0, 499);
                                    transform.Y = transform.Y.Clamp(0, 499);
                                });
                        }
                    });

            thread.Start();

            Closed += (s, e) => thread.Abort();
        }
    }
}

我的问题是这个。在这种不使用标准 WPF 动画工具的情况下,是否使用上述方法ThreadDispatcher推荐的方法?

一般来说,我有时会遇到需要更新和渲染的状态,而动画工具并不适合。所以我需要一种在单独的线程中进行更新和渲染的方法。只是想知道上述方法是否正确。

4

1 回答 1

0

上面评论中的 Clemens 建议使用DispatcherTimer. 事实上,这确实大大简化了代码。这是采用这种方法的版本:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace WpfBrownianMotion
{
    static class MiscUtils
    {
        public static double Clamp(this double n, int low, double high)
        {
            return Math.Min(Math.Max(n, low), high);
        }
    }

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            Width = 500;
            Height = 500;

            var canvas = new Canvas();

            Content = canvas;

            var transform = new TranslateTransform(250, 250);

            var circle = new Ellipse()
            {
                Width = 25,
                Height = 25,
                Fill = Brushes.PowderBlue,
                RenderTransform = transform
            };

            canvas.Children.Add(circle);

            var random = new Random();

            var timer = new DispatcherTimer();

            timer.Tick += (s, e) =>
                {
                    transform.X += -1 + random.Next(3);
                    transform.Y += -1 + random.Next(3);

                    transform.X = transform.X.Clamp(0, 499);
                    transform.Y = transform.Y.Clamp(0, 499);
                };

            timer.Start();
        }
    }
}
于 2012-11-01T12:35:13.683 回答