title: Flicker on DragMove of Border-less WPF Custom Window
body: <p>I have a custom, border-less window intended to act as a base form for future WPF projects. I've managed to simulate near all of the native window behaviours, but I'm having a problem with DragMove. I wanted the window to reposition itself above the task bar when the user drags the its title bar behind the windows task bar, so that the whole window is visible. I managed to do this by overriding the OnLocationChanged method, because all the mouse related handlers are blocked during DragMove.</p>
  
  <p>This works like a charm, except I get a flicker when dragging the title bar along the windows task bar. I can see it is trying to redraw the window where it would have been, down below, and then it immediately redraws the window again in the intended place.</p>
  
  <p>How can I interrupt this redrawing properly? Many Thanks!</p>
  
  <hr>
  
  <p><a href="https://stackoverflow.com/questions/3967432/c-sharp-wpf-dragmove-without-window-locationchanged">This</a>, <a href="https://stackoverflow.com/questions/12841909/overriding-dragmove-for-dragging-custom-controls">this</a>, <a href="https://stackoverflow.com/questions/13079407/how-to-suspend-wpf-window-to-render-before-not-all-desired-properties-are-set">this</a> and <a href="https://stackoverflow.com/questions/11703833/dragmove-and-maximize">this</a> SO question did not help me at all, unfortunately. Here is an extract of my code:</p>
  
  <pre><code>protected override void OnLocationChanged(EventArgs e)
  {
      base.OnLocationChanged(e);
  
      var activeScreenHeight = System.Windows.Forms.Screen.FromHandle(new WindowInteropHelper(this).Handle).WorkingArea.Bottom - ToolbarSnapThreshold;
      if (activeScreenHeight &lt; this.RestoreBounds.Top)
      {
          this.Top = activeScreenHeight - this.RestoreBounds.Height + ToolbarSnapThreshold;
      }
  }
  
  protected void MaximizeOrRestore()
  {
      this.WindowState = (this.WindowState == WindowState.Normal) ? WindowState.Maximized : WindowState.Normal;
      this.lastNonMinimizedState = this.WindowState;
  }
  
  protected void RestoreAndDragMove(MouseButtonState leftMouseButtonState)
  {
      if (leftMouseButtonState == MouseButtonState.Pressed)
      {
          if (this.WindowState == WindowState.Maximized)
          {
              var activeScreenWidth = System.Windows.Forms.Screen.FromHandle(new WindowInteropHelper(this).Handle).Bounds.Width;
              var windowCurrentWidth = this.RestoreBounds.Width;
  
              var windowPositionAdjustX = this.relativeMousePositionX - (windowCurrentWidth / 2);
  
              if (windowPositionAdjustX &lt; 0)
              {
                  windowPositionAdjustX = 0;
              }
              else if (windowPositionAdjustX + windowCurrentWidth &gt; activeScreenWidth)
              {
                  windowPositionAdjustX = activeScreenWidth - windowCurrentWidth;
              }
  
              this.WindowState = WindowState.Normal;
              this.lastNonMinimizedState = this.WindowState;
              this.Left = windowPositionAdjustX - this.relativeMousePositionX + this.originalMousePositionX;
              this.Top = 0 - this.relativeMousePositionY + this.originalMousePositionY;
          }
  
          this.DragMove();
      }
  }
  
  private void Window_TitleBarClicked(object sender, MouseButtonEventArgs e)
  {
      if (e.LeftButton == MouseButtonState.Pressed)
      {
          this.relativeMousePositionX = e.GetPosition(this).X;
          this.relativeMousePositionY = e.GetPosition(this).Y;
          this.originalMousePositionX = System.Windows.Forms.Cursor.Position.X;
          this.originalMousePositionY = System.Windows.Forms.Cursor.Position.Y;
  
          if (e.ClickCount == 2)
          {
              this.MaximizeOrRestore();
          }
      }
  }
  </code></pre>