C#WPF中的System.InvalidOperationException

时间:2014-10-16 03:13:02

标签: c# wpf multithreading

我想使用以下代码在WPF应用程序中移动矩形。但是,我收到以下错误:

System.InvalidOperationException:无法使用属于其他线程的DependencyObject 我查看了stackoverflow中的其他问题,但没有任何效果。

public partial class MainWindow : Window
{
    private Rectangle rect;
    int count = 1;
    Timer timer;

    public MainWindow()
    {
        InitializeComponent();
        Rectangle movedRectangle = new Rectangle();
        movedRectangle.Width = 200;
        movedRectangle.Height = 50;
        movedRectangle.Fill = Brushes.Blue;
        movedRectangle.Opacity = 0.5;
        TranslateTransform translateTransform1 = new TranslateTransform(50, 20);
        movedRectangle.RenderTransform = translateTransform1;

        this.can.Children.Add(movedRectangle);
        this.rect = movedRectangle;

        timer = new Timer(500);
        timer.Elapsed += OnTimedEvent;
        timer.Enabled = true;
    }

    private void OnTimedEvent(Object source, ElapsedEventArgs e)
    {
        count++;
        TranslateTransform translateTransform1 = new TranslateTransform(50 + count * 2, 20);
        this.rect.Dispatcher.Invoke(new Action(()=>
            rect.RenderTransform = translateTransform1));

        //this.can.UpdateLayout();
        this.can.Dispatcher.Invoke(new Action(()=>
            this.can.UpdateLayout()
            ));

    }

2 个答案:

答案 0 :(得分:0)

您正在构建UI线程外的TranslateTransformDependencyObject)。轻松修复:

        this.rect.Dispatcher.Invoke(new Action(
            () =>
            {
                TranslateTransform translateTransform1 = new TranslateTransform(50 + count * 2, 20);
                rect.RenderTransform = translateTransform1;
            }));

可以说是一个更好的解决方法:改为使用DispatcherTimer并删除所有Dispatcher.Invoke次来电。

答案 1 :(得分:0)

我建议你使用DispatcherTimer而不是普通的计时器。

请参阅以下解决方案。享受。

注意:对于DispatcherTimer,您需要为System.Windows.Threading添加程序集引用

public partial class MainWindow : Window
{
    private Rectangle rect;
    int count = 1;
    private DispatcherTimer timer = null;

    public MainWindow()
    {
        InitializeComponent();
        Rectangle movedRectangle = new Rectangle();
        movedRectangle.Width = 200;
        movedRectangle.Height = 50;
        movedRectangle.Fill = Brushes.Blue;
        movedRectangle.Opacity = 0.5;
        TranslateTransform translateTransform1 = new TranslateTransform(50, 20);
        movedRectangle.RenderTransform = translateTransform1;

        this.can.Children.Add(movedRectangle);
        this.rect = movedRectangle;

        timer = new DispatcherTimer();
        timer.Interval = new TimeSpan(0, 0, 0, 0, 500);
        timer.Tick += timer_Tick;
        timer.Start();
        timer.IsEnabled = true;

    }

    void timer_Tick(object sender, EventArgs e)
    {
        count++;
        TranslateTransform translateTransform1 = new TranslateTransform(50 + count * 2, 20);
        Dispatcher.BeginInvoke(new Action<TranslateTransform>(delegate(TranslateTransform t1)
            {
                rect.RenderTransform = t1;
                this.can.UpdateLayout();
            }), System.Windows.Threading.DispatcherPriority.Render, translateTransform1);
    }
}