Drag, Cling, Dock a dialog

Vijay Kamat 1 Reputation point
2020-04-17T02:49:08.257+00:00

Hi,

I am working on a WPF project where I will launch a new dialog inside a Window. User should be able to drag this dialog box to the edge of the window and if it is close enough, it should cling on to that side of the window like docking. User can detach it and re-attach to another side if he likes.

Can someone give me some code pointers for this.

Thank you.

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,648 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Alex Li-MSFT 1,096 Reputation points
    2020-04-20T06:08:36.66+00:00

    Welcome to our Microsoft Q&A platform!

    I made a example,you can see my code:

    ChildWindow:

       private void Window_Loaded(object sender, RoutedEventArgs e)  
            {  
                this.WindowStyle = WindowStyle.None;  
                this.Width = 200;  
                this.Height = 200;  
            }  
      
            private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)  
            {  
                if (e.LeftButton == MouseButtonState.Pressed)  
                {  
                    this.DragMove();  
      
                }  
                if (MainWindow.timer.Enabled == false)  
                {  
                    MainWindow.timer.Enabled = true;  
                }  
      
            }  
      
            private void Window_MouseRightButtonUp(object sender, MouseButtonEventArgs e)  
            {  
                if (this.Width == 20)  
                {  
                    this.Width = 200;  
                }  
            }  
    

    MainWindow

     public partial class MainWindow : Window  
        {  
            [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "SetParent")]  
            public extern static IntPtr SetParent(IntPtr childPtr, IntPtr parentPtr);  
              
          public static System.Timers.Timer timer = new System.Timers.Timer();  
            Window2 w2;  
            public MainWindow()  
            {  
                InitializeComponent();  
                w2 = new Window2();  
            }  
      
            private void Button_Click(object sender, RoutedEventArgs e)  
            {  
                w2.Show();  
                WindowInteropHelper parentHelper = new WindowInteropHelper(this);  
                WindowInteropHelper childHelper = new WindowInteropHelper(w2);  
                SetParent(childHelper.Handle, parentHelper.Handle);  
                timer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimedEvent);  
                timer.Interval = 100;  
                timer.Enabled = true;  
            }  
            public void OnTimedEvent(object sender, System.Timers.ElapsedEventArgs e)  
            {  
                this.Dispatcher.Invoke(() =>  
                {  
                    if ((w2.Left - this.Left) < 10)  
                    {  
                         
      
                        w2.Width = 20;  
      
                        timer.Enabled = false;  
                    }  
      
                });  
      
            }  
        }  
    

    7497-1.gif

    Thanks.


  2. Vijay Kamat 1 Reputation point
    2020-04-21T07:25:09.993+00:00

    Thank you for the reply, I really appreciate it.
    But the situation is a little more complicated than this.

    The dialog I want to drag is actually a usercontrol which sits in a grid column so I cant use DragMove() etc.
    Also, when I drag it out, it should come out of grid column so I can freely drag it around and when I cling it back to the left border it should sit back in the grid column.

    Can you kindly help me with this?

    I have tried this for the UserControl:

     private void titleBar_OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                if (e.LeftButton == MouseButtonState.Pressed)
                {
                    mousePosition = e.GetPosition(null);
    
    
                    if (tt.X < 10)
                    {
                       tt.X = 10;
                    }
    
                    if (tt.Y < 10)
                    {
                        tt.Y = 10;
                    }
                    this.RenderTransform = tt;
    
                    var Grid = TreeHelper.FindParent<Grid>(this);
                    Grid.ColumnDefinitions[0].Width = new GridLength(0);
                    Grid.Children.Remove(this);
                    this.Height = 1000;
                    this.Width = 400;
                }
            }
    
            private void TitleBar_OnPreviewMouseMove(object sender, MouseEventArgs e)
            {
                if (e.LeftButton == MouseButtonState.Pressed)
                {
                    tt.X +=  e.GetPosition(null).X - mousePosition.X;
                    tt.Y += e.GetPosition(null).Y - mousePosition.Y;
    
                    mousePosition = e.GetPosition(null);
    
                    if (tt.X < 10)
                    {
                        tt.X = 0;
                    }
    
                    if (tt.Y < 10)
                    {
                        tt.Y = 0;
                    }
    
                    this.RenderTransform = tt;
                }
            }
    

    But it doesnt work properly. The control disspapears when Grid column size becomes 0 and I remove it from the Grid.