Magnetic Usercontrol?

Vijay Kamat 1 Reputation point
2020-04-25T12:02:47.187+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.

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.

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.

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,670 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Alex Li-MSFT 1,096 Reputation points
    2020-04-27T04:03:54.263+00:00

    Welcome to Microsoft Q&A platform!

    You didn't provide full code,but you can see my example.

    xaml:

     <Grid>  
            <Grid.ColumnDefinitions>  
                <ColumnDefinition />  
                <ColumnDefinition/>  
            </Grid.ColumnDefinitions>  
            <Canvas Grid.Column="0" Background="AliceBlue">  
                <local:MyUserControl Width="40" Height="40" Background="Red" x:Name="usercontrol1" Canvas.Top="100" Canvas.Left="100" />  
            </Canvas>  
        </Grid>  
    

    C#

      public partial class MainWindow : Window  
        {  
            public MainWindow()  
            {  
                InitializeComponent();  
      
                usercontrol1.PreviewMouseMove += new MouseEventHandler(Element_MouseMove);  
                usercontrol1.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(Element_MouseLeftButtonDown);  
                usercontrol1.PreviewMouseLeftButtonUp += new MouseButtonEventHandler(Element_MouseLeftButtonUp);  
            }  
      
            bool isDragDropInEffect = false;  
            Point pos = new Point();  
      
            void Element_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)  
            {  
      
                  
                isDragDropInEffect = true;  
                pos = e.GetPosition(null);  
                usercontrol1.CaptureMouse();  
                usercontrol1.Cursor = Cursors.Hand;  
            }  
            void Element_MouseMove(object sender, MouseEventArgs e)  
            {  
                if (isDragDropInEffect)  
                {  
                     
                    double xPos = e.GetPosition(null).X - pos.X + (double)usercontrol1.GetValue(Canvas.LeftProperty);  
                    double yPos = e.GetPosition(null).Y - pos.Y + (double)usercontrol1.GetValue(Canvas.TopProperty);  
                    usercontrol1.SetValue(Canvas.LeftProperty, xPos);  
                    usercontrol1.SetValue(Canvas.TopProperty, yPos);  
                    pos = e.GetPosition(null);  
                }  
            }  
      
      
      
            void Element_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)  
            {  
                if (isDragDropInEffect)  
                {  
                      
                    isDragDropInEffect = false;  
                    usercontrol1.ReleaseMouseCapture();  
                }  
      
                if ((double)usercontrol1.GetValue(Canvas.LeftProperty) < 50)  
                {  
                    double i = -30;  
                    usercontrol1.SetValue(Canvas.LeftProperty, i );  
                
                }  
            }  
      
      
        }  
        public class MyUserControl : UserControl  
        {  
      
        }  
    

    7598-1.gif

    Thanks.


  2. Vijay Kamat 1 Reputation point
    2020-04-28T07:23:32.913+00:00

    Main Window:

    <Window x:Class="WpfApp1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp1"
            mc:Ignorable="d"
            Name="MyWindow"
            Title="MainWindow" Height="450" Width="800">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition>
                    <ColumnDefinition.Style>
                        <Style TargetType="ColumnDefinition">
                            <Setter Property="Width"
                                    Value="0" />
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding PanelExpanded,ElementName=MyWindow, Mode=TwoWay}"
                                             Value="True">
                                    <Setter Property="Width"
                                            Value="{Binding PanelWidth, ElementName=MyWindow}" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </ColumnDefinition.Style>
                </ColumnDefinition>
                <ColumnDefinition 
                                  Width="*" />
                </Grid.ColumnDefinitions>
    
            <local:MyUserControl Grid.Column="0"/>
    
            <TabControl Grid.Column="1"/>
    
        </Grid>
    </Window>
    

    Code Behind Main Window:

     public partial class MainWindow : Window
        {
            public bool PanelExpanded { get; set; }
    
    
            public double PanelWidth { get; set; }
    
            public MainWindow()
            {
                PanelExpanded = true;
                PanelWidth = 150;
    
                InitializeComponent();
            }
    
    
        }
    

    My User control:

     <Grid>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="30" />
                    <RowDefinition Height="*" />
                </Grid.RowDefinitions>
                <Border Name="titleBar"
                        Grid.Row="0"
                        HorizontalAlignment="Stretch"
                        VerticalAlignment="Stretch"
                        Background="Gray"
                        PreviewMouseLeftButtonDown="titleBar_OnPreviewMouseLeftButtonDown"
                        PreviewMouseMove="TitleBar_OnPreviewMouseMove" />
    
    
            </Grid>
        </Grid>
    

    Code Behind My user control:

    public partial class MyUserControl : UserControl
    {
    public MyUserControl()
    {
    InitializeComponent();
    tt = new TranslateTransform();
    }

        private Point mousePosition;
        private TranslateTransform tt;
    
        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;
                }
    
    
                var Grid = FindParent<Grid>(this);
                Grid.ColumnDefinitions[0].Width = new GridLength(0);
    
                if (Grid.GetColumn(this) == 0)
                {
                    Grid.SetColumn(this, 1);
                    Grid.SetColumnSpan(this, 2);
    
                    tt.X = 10;
                    tt.Y = 10;
                    this.RenderTransform = tt;
    
    
                    this.Height = 400;
                    this.Width = 150;
                }
            }
        }
    
        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;
            }
        }
    
        public static T FindParent<T>(DependencyObject child) where T : DependencyObject
        {
            //get parent item
            DependencyObject parentObject = VisualTreeHelper.GetParent(child);
    
            //we've reached the end of the tree
            if (parentObject == null) return null;
    
            //check if the parent matches the type we're looking for
            T parent = parentObject as T;
            if (parent != null)
                return parent;
            else
                return FindParent<T>(parentObject);
        }
    
    }
    
    0 comments No comments