单击并拖动WPF中的选择框

时间:2009-12-03 06:55:25

标签: c# wpf mouse selection drag

是否可以在WPF中实现鼠标单击和拖动选择框。是否应该通过简单地绘制矩形,计算其点的坐标和评估此框内其他对象的位置来完成?还是有其他方法吗?

您能提供一些示例代码或链接吗?

4 个答案:

答案 0 :(得分:39)

以下是我过去用于绘制拖动选择框的简单技术的示例代码。

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;
            }
        }
    }
}

答案 1 :(得分:5)

通过添加InkCanvas并将其EditingMode设置为Select,您可以非常轻松地获得此功能。虽然它主要用于Tablet PC墨水的收集和渲染,但它很容易用作基本的设计器表面。

<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>

答案 2 :(得分:0)

该项目创建了一个自定义MultiSelector,它支持多种选择方法,包括矩形“套索”样式:

Developing a MultiSelector by Teofil Cobzaru

在这里复制太久了。设计的关键要素IIRC是创建自定义ItemContainer,该自定义MultiSelector知道如何与其父ListBoxItem进行交互。这类似于ListBox / ItemsControl

这可能不是最简单的方法,但是,如果您已经使用某种类型的rindx=df[((df['id'] == 1) & (df['value'] > 100)) | ((df['id'] == 2) & (df['value'] < 100))].index df.loc[rindx,'threshold']= 1 rindx=df[((df['id'] == 1) & (df['value'] < 101)) | ((df['id'] == 2) & (df['value'] > 99))].index df.loc[rindx,'threshold']= 0 ## fillna df['threshold'] = df['threshold'].fillna(df['value']).astype(int) 来托管可能需要选择的项目,则可以很容易地将其放入该设计中。

答案 3 :(得分:-1)

MouseDown逻辑:

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);