[英]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.