Search code examples
c#wpfmouseselectiondrag

Click and drag selection box in WPF


Is it possible to implement mouse click and drag selection box in WPF. Should it be done through simply drawing a rectangle, calculating coordinates of its points and evaluating position of other objects inside this box? Or are there some other ways?

Could you give a bit of sample code or a link?


Solution

  • Here is sample code for a simple technique that I have used in the past to draw a drag selection box.

    XAML:

    <Window x:Class="DragSelectionBox.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300"
        >
        <Grid
            x:Name="theGrid"
            MouseDown="Grid_MouseDown"
            MouseUp="Grid_MouseUp"
            MouseMove="Grid_MouseMove"
            Background="Transparent"
            >
            <Canvas>
                <!-- This canvas contains elements that are to be selected -->
            </Canvas>
            
            <Canvas>
                <!-- This canvas is overlaid over the previous canvas and is used to 
                    place the rectangle that implements the drag selection box. -->
                <Rectangle
                    x:Name="selectionBox"
                    Visibility="Collapsed"
                    Stroke="Black"
                    StrokeThickness="1"
                    />
            </Canvas>
        </Grid>
    </Window>
    

    C#:

    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
        }
    
        bool mouseDown = false; // Set to 'true' when mouse is held down.
        Point mouseDownPos; // The point where the mouse button was clicked down.
    
        private void Grid_MouseDown(object sender, MouseButtonEventArgs e)
        {
            // Capture and track the mouse.
            mouseDown = true;
            mouseDownPos = e.GetPosition(theGrid);
            theGrid.CaptureMouse();
    
            // Initial placement of the drag selection box.         
            Canvas.SetLeft(selectionBox, mouseDownPos.X);
            Canvas.SetTop(selectionBox, mouseDownPos.Y);
            selectionBox.Width = 0;
            selectionBox.Height = 0;
            
            // Make the drag selection box visible.
            selectionBox.Visibility = Visibility.Visible;
        }
    
        private void Grid_MouseUp(object sender, MouseButtonEventArgs e)
        {
            // Release the mouse capture and stop tracking it.
            mouseDown = false;
            theGrid.ReleaseMouseCapture();
            
            // Hide the drag selection box.
            selectionBox.Visibility = Visibility.Collapsed;
            
            Point mouseUpPos = e.GetPosition(theGrid);
            
            // TODO: 
            //
            // The mouse has been released, check to see if any of the items 
            // in the other canvas are contained within mouseDownPos and 
            // mouseUpPos, for any that are, select them!
            //
        }
    
        private void Grid_MouseMove(object sender, MouseEventArgs e)
        {
            if (mouseDown)
            {
                // When the mouse is held down, reposition the drag selection box.
                
                Point mousePos = e.GetPosition(theGrid);
    
                if (mouseDownPos.X < mousePos.X)
                {
                    Canvas.SetLeft(selectionBox, mouseDownPos.X);
                    selectionBox.Width = mousePos.X - mouseDownPos.X;
                }
                else
                {
                    Canvas.SetLeft(selectionBox, mousePos.X);
                    selectionBox.Width = mouseDownPos.X - mousePos.X;
                }
    
                if (mouseDownPos.Y < mousePos.Y)
                {
                    Canvas.SetTop(selectionBox, mouseDownPos.Y);
                    selectionBox.Height = mousePos.Y - mouseDownPos.Y;
                }
                else
                {
                    Canvas.SetTop(selectionBox, mousePos.Y);
                    selectionBox.Height = mouseDownPos.Y - mousePos.Y;
                }
            }
        }
    }
    

    I wrote an article about this:

    https://www.codeproject.com/Articles/148503/Simple-Drag-Selection-in-WPF