是否可以在WPF中实现鼠标单击和拖动选择框。是否应该通过简单地绘制矩形,计算其点的坐标和评估此框内其他对象的位置来完成?还是有其他方法吗?
您能提供一些示例代码或链接吗?
答案 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)
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);