在特定鼠标位置拖放到 TextBox - 显示插入符号或位置指示符
Posted
技术标签:
【中文标题】在特定鼠标位置拖放到 TextBox - 显示插入符号或位置指示符【英文标题】:Drag and drop an to TextBox in a specific mouse position - Show caret or position indicator 【发布时间】:2016-12-18 13:10:07 【问题描述】:我正在将一个项目从 TreeView
粘贴到 TextBox
,但我想将该项目粘贴到鼠标的当前位置,并显示如下图所示的插入符号。
带有插入符号的图像:
这是我的代码:
private void tvOperador_ItemDrag(object sender, ItemDragEventArgs e)
var node = (TreeNode)e.Item;
if (node.Level > 0)
DoDragDrop(node.Text, DragDropEffects.Copy);
private void txtExpresion_DragEnter(object sender, DragEventArgs e)
if (e.Data.GetDataPresent(typeof(string))) e.Effect = DragDropEffects.Copy;
private void txtExpresion_DragDrop(object sender, DragEventArgs e)
if (e.Data.GetDataPresent(typeof(System.String)))
string Item = (System.String)e.Data.GetData(typeof(System.String));
string[] split = Item.Split(':');
txtExpresion.Text += split[1];
【问题讨论】:
查看更新后的答案,它融合了我原来的最佳解决方案和@Reza 的解决方案! 【参考方案1】:这很棘手,因为 Drag&Drop
操作会捕获鼠标,因此您不能使用鼠标事件..
一种方法是设置Timer
来完成这项工作..:
Timer cursTimer = new Timer();
void cursTimer_Tick(object sender, EventArgs e)
int cp = txtExpresion.GetCharIndexFromPosition(
txtExpresion.PointToClient(Control.MousePosition));
txtExpresion.SelectionStart = cp;
txtExpresion.SelectionLength = 0;
txtExpresion.Refresh();
Timer
使用 Control.MousePosition
函数每 25 毫秒左右确定一次光标位置,设置插入符号并更新 TextBox
。
在您的事件中初始化它并确保TextBox
具有焦点;最后在当前选择处添加字符串:
private void txtExpresion_DragEnter(object sender, DragEventArgs e)
if (e.Data.GetDataPresent(typeof(string)))
e.Effect = DragDropEffects.Copy;
txtExpresion.Focus();
cursTimer = new Timer();
cursTimer.Interval = 25;
cursTimer.Tick += cursTimer_Tick;
cursTimer.Start();
private void txtExpresion_DragDrop(object sender, DragEventArgs e)
if (e.Data.GetDataPresent(typeof(System.String)))
cursTimer.Stop();
string Item = (System.String)e.Data.GetData(typeof(System.String));
string[] split = Item.Split(':');
txtExpresion.SelectedText = split[1]
解决此问题的另一种方法是不使用普通的拖放操作,而只对鼠标事件进行编码,但在我的第一次测试中这个工作正常。
更新
虽然上述解决方案确实有效,但使用Timer
似乎并不完全优雅。如 Reza 的回答所示,使用 DragOver
事件要好得多。但是,与其画一个光标,不如做真实的事情,即控制实际的工字梁..?
DragOver
事件在移动过程中一直被调用,所以它的工作方式与MousMove
非常相似:所以这是两种解决方案的合并,我认为这是最好的方法:
private void txtExpresion_DragDrop(object sender, DragEventArgs e)
if (e.Data.GetDataPresent(typeof(System.String)))
string Item = (System.String)e.Data.GetData(typeof(System.String));
string[] split = Item.Split(':');
txtExpresion.SelectionLength = 0;
txtExpresion.SelectedText = split[1];
private void txtExpresion_DragEnter(object sender, DragEventArgs e)
if (e.Data.GetDataPresent(typeof(string)))
e.Effect = DragDropEffects.Copy;
txtExpresion.Focus();
private void txtExpresion_DragOver(object sender, DragEventArgs e)
int cp = txtExpresion.GetCharIndexFromPosition(
txtExpresion.PointToClient(Control.MousePosition));
txtExpresion.SelectionStart = cp;
txtExpresion.Refresh();
【讨论】:
【参考方案2】:您可以在DragOver
事件中在TextBox
上画一个插入符号。还将SelectionStart
设置为从鼠标位置获得的字符索引。然后在DragDrop
事件中,设置SelectedText
。
private void textBox1_DragOver(object sender, DragEventArgs e)
if (e.Data.GetDataPresent(typeof(System.String)))
var position = textBox1.PointToClient(Cursor.Position);
var index = textBox1.GetCharIndexFromPosition(position);
textBox1.SelectionStart = index;
textBox1.SelectionLength = 0;
textBox1.Refresh();
using (var g = textBox1.CreateGraphics())
var p = textBox1.GetPositionFromCharIndex(index);
g.DrawLine(Pens.Black, p.X, 0, p.X, textBox1.Height);
private void textBox1_DragDrop(object sender, DragEventArgs e)
if (e.Data.GetDataPresent(typeof(System.String)))
string txt = (System.String)e.Data.GetData(typeof(System.String));
textBox1.SelectedText = txt;
【讨论】:
这是一个非常好的选择! @Reza:你能告诉我你是用什么制作那个动画的吗? @TaW 感谢您的反馈 :) 我使用了ScreenToGif。此工具可让您记录屏幕的选定区域并将其保存为 Gif。 我在 gif 中看到了放置位置指示器的黑色阴影,但在执行时它在TextBox
中不存在。这只是为了 gif 的质量或采样率。在运行时完全清楚。
嗯,我没看到影子。但后来我睡着了;-)以上是关于在特定鼠标位置拖放到 TextBox - 显示插入符号或位置指示符的主要内容,如果未能解决你的问题,请参考以下文章
如何让人们将 LI 拖放到列表中的特定位置? (console.log 问题)
将行动态添加到TableLayoutPanel会在不同的行号(位置)上显示