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

标签 .net winforms treeview textbox drag-and-drop

我在 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);
        }
    }

最佳答案

在所有这些关于拖放的建议中,我错过的是使文本插入符号可见。最终,我发现您只需将焦点设置到控件中即可!因此,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;
}

关于.net - 接受 Drop 时如何在文本框上移动插入插入符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/913735/

相关文章:

c# - C# Winforms 应用程序中总进程内存使用量的自相矛盾的报告

c# - 如何创建自定义消息框?

algorithm - 添加 TreeView 分支的最有效算法

c# - .NET BCL API 或框架方法的时间复杂度

c# - 缺少程序集时,.NET 应用程序静默无法启动

c# - 图表绑定(bind)到非原始类型

c# - 为什么在winforms应用程序中点击treeview节点时会出现异常?

c# - 没有预期异常的测试

.net - 我应该在数据访问层中保留sqlconnection吗?

Python Gtk3 Treeview 过滤和编辑