问题描述
我希望能够拖过一堆控件并选择特定类型的控件(文本框).
I want to be able to drag over a bunch of controls and select those of a certain type (TextBoxes).
拖动操作完成后,我想显示一个输入框(是的,我必须引用/使用 VB .dll),提示用户输入将在每个选定的 TextBox 中输入的值.
Once the dragging action has been completed, I want to display an inputbox (yes, I'll have to reference/use the VB .dll) prompting the user for the value that will be entered in each selected TextBox.
这可以吗?(当然,但是怎么做?)
Can this be done? (of course, but how?)
或者是否有其他方法可以完成相同的事情(允许用户快速选择多个控件,然后一次对所有控件执行操作)?
Or is there another way to accomplish the same thing (allow the user to quickly select multiple controls and then perform an action on all of them at once)?
我已经完成了这种工作——警告"或陷阱"是我必须向用户弹出 MessageBox.Show() 才能使其工作.本质上,我:
I've got this sort of working - the "caveat" or "gotcha" being that I have to pop up a MessageBox.Show() to the user for it to work. Essentially, I:
如果选择了鼠标右键,则在容器(在我的情况下为 FlowLayoutPanel)MouseDown 事件上将布尔值设置为 true.
Set a boolean to true on the container's (FlowLayoutPanel, in my case) MouseDown event, if the right mouse button was selected.
如果选择了鼠标右键,则在容器的 MouseUp 事件中将该布尔值设置为 false.
Set that same boolean to false on the container's MouseUp event, if the right mouse button was selected.
然后,我为该表单上的所有 TextBoxes 共享了一个 MouseHover 事件处理程序,如果布尔值为 true,则更改 BackColor(在我的情况下,从 Window 更改为 Gainsboro).
I then have a shared MouseHover event handler for all of the TextBoxes on that form that, if the boolean is true, changes the BackColor (to Gainsboro, in my case, from Window).
在容器的 MouseUp 事件中,我还使用 InputBox(引用/导入/使用 VB .dll)请求用户输入突出显示"文本框常用的值.然后我遍历它们,寻找具有该 BackColor 的那些,并将用户提供的值分配给它们的 Text 属性.
In the container's MouseUp event, I also use an InputBox (referencing/importing/using the VB .dll) requesting the user enter the value that will be common for the "highlighted" TextBoxes. I then loop through them, looking for those with that BackColor, and assing the user-supplied value to their Text properties.
瞧!
不幸的是,当您以这种方式为其赋值时,TextBoxes 的 Modified 属性似乎没有改变,所以我不得不解决这个问题(明确地将保存"按钮设置为启用),并且我不得不添加更多代码复制我的 KeyPressed 代码,它限制了用户输入的值.
Unfortunately, the TextBoxes' Modified property does not seem to be altered when you assign it values this way, so I had to work around that (explicitly setting the "Save" button to enabled), and I had to add more code to duplicate my KeyPressed code which limits the values entered by the user.
所以,这当然是可能的,尽管有点笨拙.不过,我还没有确定 MessageBox.Show() 是错误"还是功能......
So, it is, of course, possible, albeit a little kludgy. I haven't decided if the MessageBox.Show() is a "bug" or a feature, though...
相关帖子是:为什么 MouseHover 事件只有在 messagebox.show() 或断点发生在它之前才被调用?
推荐答案
这个其实很简单.我假设通过拖动您的意思是您想要选择"控件,例如您将在绘画程序中选择"一些像素.这是我写给你的一个例子,它就是这样做的,只选择 TextBox 控件.它会忽略其他控件.
This is actually very simple. I assume by drag you mean that you want to 'select' controls, like you would 'select' some pixels in a paint program for example. Here is an example I wrote you that does just this and only selects TextBox controls. It ignores other controls.
namespace WindowsFormsApplication5
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
/// <summary>
/// Main application form
/// </summary>
public partial class Form1 : Form
{
/// <summary>
/// Initializes a new instance of the WindowsFormsApplication5.Form1 class
/// </summary>
public Form1() {
InitializeComponent();
DoubleBuffered = true;
}
private Point selectionStart;
private Point selectionEnd;
private Rectangle selection;
private bool mouseDown;
private void GetSelectedTextBoxes() {
List<TextBox> selected = new List<TextBox>();
foreach (Control c in Controls) {
if (c is TextBox) {
if (selection.IntersectsWith(c.Bounds)) {
selected.Add((TextBox)c);
}
}
}
// Replace with your input box
MessageBox.Show("You selected " + selected.Count + " textbox controls.");
}
protected override void OnMouseDown(MouseEventArgs e) {
selectionStart = PointToClient(MousePosition);
mouseDown = true;
}
protected override void OnMouseUp(MouseEventArgs e) {
mouseDown = false;
SetSelectionRect();
Invalidate();
GetSelectedTextBoxes();
}
protected override void OnMouseMove(MouseEventArgs e) {
if (!mouseDown) {
return;
}
selectionEnd = PointToClient(MousePosition);
SetSelectionRect();
Invalidate();
}
protected override void OnPaint(PaintEventArgs e) {
base.OnPaint(e);
if (mouseDown) {
using (Pen pen = new Pen(Color.Black, 1F)) {
pen.DashStyle = DashStyle.Dash;
e.Graphics.DrawRectangle(pen, selection);
}
}
}
private void SetSelectionRect() {
int x, y;
int width, height;
x = selectionStart.X > selectionEnd.X ? selectionEnd.X : selectionStart.X;
y = selectionStart.Y > selectionEnd.Y ? selectionEnd.Y : selectionStart.Y;
width = selectionStart.X > selectionEnd.X ? selectionStart.X - selectionEnd.X : selectionEnd.X - selectionStart.X;
height = selectionStart.Y > selectionEnd.Y ? selectionStart.Y - selectionEnd.Y : selectionEnd.Y - selectionStart.Y;
selection = new Rectangle(x, y, width, height);
}
}
}
目前对此存在限制.显而易见的是,这不会选择嵌套容器控件中的 TextBox(例如,表单上包含 TextBox 的面板).如果是这种情况,将在面板下方绘制选择,并且不会选择 TextBox,因为我编写的代码不会检查嵌套容器.
Now there are limitations with this currently. The obvious is that this will not select a TextBox within a nested container control (eg. a panel on your form containing a TextBox). If that were the case the selection would be drawn underneath the panel, and the TextBox would not be selected because the code I wrote does not check nested containers.
不过,您可以轻松更新代码来完成所有这些工作,但这应该会给您一个良好的开端.
You can easily update the code to do all of this however, but this should give you a solid start.
这篇关于如何通过鼠标拖动来选择多个控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!