简体   繁体   English

C#WPF中的System.InvalidOperationException

[英]System.InvalidOperationException in C# WPF

I want to move a rectangle in WPF application using the following code. 我想使用以下代码在WPF应用程序中移动一个矩形。 However, I am getting the following error: 但是,我收到以下错误:

System.InvalidOperationException: Cannot use a DependencyObject that belongs to a different thread I looked at other problems in stackoverflow but nothing worked. 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()
            ));

    }

You are constructing a TranslateTransform (which is a DependencyObject ) outside the UI thread. 您正在UI线程外部构造TranslateTransform (这是DependencyObject )。 Easy fix: 轻松解决:

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

Arguably a better fix: use a DispatcherTimer instead and get rid of all your Dispatcher.Invoke calls. 可以说是更好的解决方案:改用DispatcherTimer并摆脱所有的Dispatcher.Invoke调用。

I would suggest you to use DispatcherTimer than a normal timer. 我建议您使用DispatcherTimer而不是普通的计时器。

Please see the below solution. 请参阅以下解决方案。 enjoy. 请享用。

Note: for DispatcherTimer you will need to add the assembly reference for System.Windows.Threading 注意:对于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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM