Click and drag selection box in WPF

后端 未结 4 1558
攒了一身酷
攒了一身酷 2020-11-30 21:53

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 evalua

相关标签:
4条回答
  • 2020-11-30 22:01

    MouseDown logic:

    MouseRect.X = mousePos.X >= MouseStart.X ? MouseStart.X : mousePos.X;
    MouseRect.Y = mousePos.Y >= MouseStart.Y ? MouseStart.Y : mousePos.Y;
    MouseRect.Width = Math.Abs(mousePos.X - MouseStart.X);
    MouseRect.Height = Math.Abs(mousePos.Y - MouseStart.Y);
    
    0 讨论(0)
  • 2020-11-30 22:21

    This project created a custom MultiSelector which supports several selection methods including a rectangular "lasso" style:

    Developing a MultiSelector by Teofil Cobzaru

    It is far too long to reproduce here. The key elements of the design, IIRC, were to create a custom ItemContainer which knows how to interact with its MultiSelector parent. This is analagous to ListBoxItem / ListBox.

    This is probably not the simplest possible approach, however if you are already using some type of ItemsControl to host the items which may need to be selected, it could fit into that design pretty easily.

    0 讨论(0)
  • 2020-11-30 22:22

    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;
                }
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-30 22:22

    You can get this functionality pretty easily by adding an InkCanvas and set its EditingMode to Select. Although it's primarily intended for Tablet PC ink collection and rendering, it's very easy to use it as a basic designer surface.

    <Window Width="640" Height="480" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
        <InkCanvas EditingMode="Select">
            <Button Content="Button" Width="75" Height="25"/>
            <Button Content="Button" Width="75" Height="25"/>
        </InkCanvas>
    </Window>
    
    0 讨论(0)
提交回复
热议问题