首页 > 解决方案 > 如果属性是从另一个进程更新的,PropertyChanged 不起作用?

问题描述

问题是:如果另一个窗口改变位置,我希望我的窗口改变位置。我在另一个线程中运行了一个函数,该函数每 50 毫秒检查另一个窗口位置。如果我直接从另一个进程更改 myWindow.Left 和 myWindow.Top ,那么一切正常:

 Application.Current.Dispatcher.Invoke((System.Action)delegate{
     this.Left = newTablePosition.Left + xShift;
     this.Top = newTablePosition.Top + yShift;                     
 });

但它不起作用,如果我尝试将 Window.Left 绑定到 X 并将 Window.Top 绑定到 Y,然后从另一个线程更改 X 和 Y。我已经实现了 INotifyPropertyChanged:

public double X{
        set{
            x = value;              
            OnPropertyChanged(nameof(X));            
        }
        get{return x;}
    }
    private double y;
    public double Y {
        set{
            y = value;
            OnPropertyChanged(nameof(Y));
        }
        get{return y;}
    }

但是这段代码不会调用我的窗口移动:

  Application.Current.Dispatcher.Invoke((System.Action)delegate{
                    X = newTablePosition.Left + xShift + HUDPosition.x;
                    Y = newTablePosition.Top + yShift + HUDPosition.y;  })

我以这种方式调用此代码:

  Thread newthread = new Thread(CheckTablePosition){IsBackground = true};
        isActive = true;
        newthread.Start();

和功能:

public void
    CheckTablePosition(){
        while (isActive){
            Thread.Sleep(50);
            var newTablePosition = new TablePosition(_table.hWnd);   
            if (_tablePosition.IsEqual(newTablePosition)){
                continue;
            }
            _tablePosition = newTablePosition;
            var xShift = (int) (newTablePosition.Width * _defaultPosition.x);
            var yShift  = (int) (newTablePosition.Height * _defaultPosition.y);

            try {
                Application.Current.Dispatcher.Invoke((System.Action)delegate{
                    this.Left = newTablePosition.Left + xShift + HUDPosition.x;
                    this.Top = newTablePosition.Top + yShift + HUDPosition.y;                     
                    OnPropertyChanged(nameof(Y));});
            }
            catch(Exception ex) {
                MessageBox.Show(ex.ToString());
                break;
            }
            
        }
    }


 

标签: c#wpfmultithreadinginvokeinotifypropertychanged

解决方案


它有如此简单的解决方案。我将绑定更改为双向绑定,现在可以使用:

 Left="{Binding X, Mode=TwoWay}"

推荐阅读