这很棘手,因为拖放(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]
}
}
另一种解决方法是不使用普通的拖放,只编写鼠标事件,但在我的第一次测试中,这个方法可行。
更新:虽然上面的解决方案确实可行,但使用计时器似乎不是很优雅。最好使用DragOver事件,就像Reza的回答中所示。但是,为什么不做真正的事情,也就是控制实际的I-beam呢? DragOver事件在移动过程中一直调用,因此它的工作方式几乎与MouseMove相同。因此,以下是两个解决方案的合并,我认为这是最好的方法:
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();
}