2016-08-11 162 views
1

我正將一個項目從TreeView粘貼到TextBox,但我想將該項目粘貼到鼠標當前位置並顯示一個插入符號下面的圖片。 圖像的插入符號: example將文本框拖放到特定的鼠標位置 - 顯示插入符號或位置指示器

這裏是我的代碼:

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]; 
    } 
} 
+0

看到更新的答案,它融合了最好的我原來的和禮的解決方案的@! – TaW

回答

2

這是棘手的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似乎並不完全優雅。從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(); 

} 
1

您可以在DragOver事件中勾畫TextBox。還要將SelectionStart設置爲從鼠標位置獲得的字符索引。然後在DragDrop事件中,只需設置SelectedText

enter image description here

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; 
    } 
} 
+0

這是一個非常不錯的選擇! @Reza:你能告訴我你製作動畫的過程嗎? – TaW

+0

@TaW感謝您的反饋:)我用[ScreenToGif](https://screentogif.codeplex.com/)。這個工具可以讓你記錄屏幕上的選定區域並保存爲Gif。 –

+0

我在gif中看到了拖放位置指示器的陰影,但執行時它不存在於「TextBox」中。這只是爲了gif的質量或採樣率。在運行時它是完全清楚的。 –