2016-08-11 19 views
1

TreeViewからTextBoxにアイテムを貼り付けていますが、そのアイテムをマウスの現在の位置にペーストして、下の画像。キャレットと 画像:ここで example特定のマウス位置にテキストボックスをドラッグアンドドロップする - キャレットまたは位置のインジケータを表示する

が私のコードです:あなたはマウスイベントを使用することはできませんのでDrag&Drop操作は、マウス撮影し続けるよう

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

これはトリッキーな..です

一つの方法は、仕事をするために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(); 
    } 

TimerControl.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] 
     } 
    } 

それを解決するための別の方法は、マウスイベント通常のドラッグ&ドロップとコードのみを使用しますが、この1つは[OK]を私の最初のテストを働いていないことであろう。

更新

上記溶液は仕事をしながら、Timerを使用すると、正確にエレガントないようです。 Rezaの答えに見られるように、DragOverイベントを使用するほうがはるかに優れています。カーソルをペイントするのではなく、実際のI-beamをコントロールしてみましょう。

それはかなりMousMoveのように動作しますので、DragOverイベントが移動中にすべての時間と呼ばれます:だから、ここで私はそれを行うための最善の方法であると信じて2つのソリューションの合併である:

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

TextBox以上のキャレットをDragOverイベントに描画することができます。また、SelectionStartをマウスの位置から取得するcharインデックスに設定します。その後、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の品質やサンプリングレートのためのものです。実行時には完全にはっきりしています。 –