c# - 将 an 拖放到特定鼠标位置的 TextBox - 显示插入符号或位置指示器

标签 c# winforms textbox drag-and-drop treeview

我正在将一个项目从 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];
    }
}

最佳答案

这很棘手,因为拖放 操作会一直捕获 鼠标,因此您不能使用鼠标事件..

一种方法是设置一个 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 函数每 25 毫秒左右确定一次光标位置,设置插入符号并更新 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();

}

关于c# - 将 an 拖放到特定鼠标位置的 TextBox - 显示插入符号或位置指示器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38902392/

相关文章:

c# - C# .NET 中的表单

javascript - 如何使用javascript检查文本框中的第一个字符是否为数字?

c# - 是否可以将 LINQ "Take"扩展方法的结果转换为原始类型?

c# - 滚动问题

c# - 获得对 "fall through"面板的点击

c# - Excel VBA 和 C# DLL : Instantiate WinForms Object can only be done once. 第二次尝试时出现错误

c# - 添加迁移时无法加载文件或程序集网络标准

c# - 在后台线程中创建 wpf 控件

c# - 从 C# 中的 List<string> 中删除重复项

jquery - 我想在单击 #gen 后使用文本框值设置 <a> href?