[英]Drag and drop an to TextBox in a specific mouse position - Show caret or position indicator
我将一个项目从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];
}
}
这很棘手,因为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
函数每隔25ms左右确定光标位置,设置插入符号并更新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
,似乎不完全是优雅 。 使用DragOver
事件要好得多,如Reza的答案所示。 但是,不是绘制光标,为什么不做真实的事情,即控制实际的工字梁..?
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();
}
您可以在DragOver
事件中在TextBox
绘制插入符号。 同时将SelectionStart
设置为从鼠标位置获取的char索引。 然后在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;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.