如何在接受Drop时在文本框上移动插入符号

Ted*_*ott 2 .net treeview textbox drag-and-drop winforms

我在Windows窗体中的同一窗体上有一个TreeView和一个多行文本框.我有拖放设置,以便我可以将节点从TreeView拖到文本框并将文本插入文本框(这是有效的).

我想增强这一点,以便当鼠标拖过文本框时,某些指示符会在文本中移动,显示用户将文本插入的位置,并且当放下它时会插入该位置.目前我只是把文本放在SelectionStart,但是拖动操作不会更新SelectionStart,所以它在用户最后有光标的时候.

这是我目前的代码:

    private void treeView1_ItemDrag(object sender, ItemDragEventArgs e)
    {
        if (e.Button != MouseButtons.Left)
            return;

        object item = e.Item;
        treeView1.DoDragDrop(((TreeNode)item).Tag.ToString(), DragDropEffects.Copy | DragDropEffects.Scroll);
    }

    private void textBox1_DragEnter(object sender, DragEventArgs e)
    {
        if (e.Data.GetDataPresent(DataFormats.StringFormat))
        {
            e.Effect = DragDropEffects.Copy | DragDropEffects.Scroll;
        }
        else
        {
            e.Effect = DragDropEffects.None;
        }
    }

    private void textBox1_DragDrop(object sender, DragEventArgs e)
    {
        if (e.Data.GetDataPresent(DataFormats.StringFormat))
        {
            textBox1.SelectionLength = 0;
            textBox1.SelectedText = (string)e.Data.GetData(DataFormats.StringFormat);
        }
    }
Run Code Online (Sandbox Code Playgroud)

use*_*106 8

在所有这些关于拖放的建议中我错过的是使文本插入符号可见.最后,我发现你只需要将焦点设置到控件中!因此textBox1.DragOver事件处理程序的最终代码如下所示.我已经包含了上一个答案中的GetCaretIndexFromPoint函数:

/// <summary>
/// Gives visual feedback where the dragged text will be dropped.
/// </summary>
private void textBox1_DragOver(Object sender, System.Windows.Forms.DragEventArgs e)
{
    // fake moving the text caret
    textBox1.SelectionStart = GetCaretIndexFromPoint(textBox1, e.X, e.Y);
    textBox1.SelectionLength = 0;
    // don't forget to set focus to the text box to make the caret visible!
    textBox1.Focus();
}

/// <remarks>
/// GetCharIndexFromPosition is missing one caret position, as there is one extra caret
/// position than there are characters (an extra one at the end).
/// </remarks>
private int GetCaretIndexFromPoint(System.Windows.Forms.TextBox box, int x, int y)
{
    Point realPoint = box.PointToClient(newPoint(x, y));
    int index = box.GetCharIndexFromPosition(realPoint);
    if (index == box.Text.Length - 1)
    {
        Point caretPoint = box.GetPositionFromCharIndex(index);
        if (realPoint.X > caretPoint.X)
        {
            index += 1;
        }
    }
    return index;
}
Run Code Online (Sandbox Code Playgroud)