这很棘手,因为 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();
}