Search code examples
c#wpfmultithreadinginvokeinotifypropertychanged

PropertyChanged doesn't work if property was updated from another process?


The problem is: I want my window change position if another window changes position. I have ran a function in another thread that checks another window position every 50 millisecond. All is working if I change myWindow.Left and myWindow.Top from another process directly like that:

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

But it doesn't work, if I try to bind my Window.Left to X and Window.Top to Y, and then change X and Y from another thread. I have implemented 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;}
    }

But this code doesn't invoke my window move:

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

I am calling this code in a such way:

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

And function:

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


 

Solution

  • It has so easy solution. I changed binding to TwoWay binding and it works now:

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