在WPF中是否能够实现鼠标点击和拖动选框?应该通过简单绘制一个矩形、计算其点的坐标并评估此框内其他对象的位置来完成吗?还是有其他方法?
您能提供一些示例代码或链接吗?
以下是我过去使用的简单技巧的示例代码,用于绘制拖动选择框。
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;
}
}
}
}
我写了一篇关于这个的文章:
https://www.codeproject.com/Articles/148503/Simple-Drag-Selection-in-WPF
通过添加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>
这个项目创建了一个自定义的MultiSelector
,支持多种选择方法,包括矩形“套索”样式:
由Teofil Cobzaru开发的MultiSelector
这里不可能全部复制。设计的关键要素是创建一个自定义的ItemContainer
,它知道如何与其MultiSelector
父级交互。这类似于ListBoxItem
/ListBox
。
这可能不是最简单的方法,但如果您已经在使用某种类型的ItemsControl
来托管可能需要被选择的项,那么它可以很容易地适应该设计。
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);