【问题标题】:Best way to stop a datagridview object from getting clicked and stealing focus阻止 datagridview 对象被点击和窃取焦点的最佳方法
【发布时间】:2016-10-19 21:39:30
【问题描述】:

我的表单上有两个数据网格视图。我有一个(dgv1)用于编辑数据,一个(dgv2)仅用于查看(捕获点击操作)。例如,我可能正在编辑 dgv1 中的一个单元格(文本),并且需要双击 dgv2 中的一行以将内容放入 dgv1(类似于快速复制/粘贴)。目前我必须在 dgv2 上使用鼠标右键双击事件,因为如果在任何时候我左键单击或左键双击,焦点将从 dgv1 移动到 dgv2 并停止编辑我正在处理的 dgv1 单元格。

我想看看是否可以通过鼠标左键双击dgv2来完成我正在做的事情?

我唯一能想到的就是尝试找到一种方法来禁用鼠标左键单击事件,但我希望基本上只是让它“不响应”,就像你双击单元格时一样/行。

想法?

编辑:dgv2 CellMouseDoubleClick 事件示例

private void dgv2_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
{
    if (e.Button != MouseButtons.Right) return;

    DataGridView dgvSrc = (DataGridView)sender;
    DataGridView dgvDest = dgv1;

    DataGridViewCell cellSrc = dgvSrc.Rows[e.RowIndex].Cells["dgv2VariableName"];

    foreach (DataGridViewCell cell in dgvDest.SelectedCells)
    {
        if (cell.IsInEditMode && dgvDest.CurrentCell.EditType == typeof(DataGridViewTextBoxEditingControl))
        {
            //Target inserting the variable in the current selected edited area inside the textbox
            TextBox editBox = (TextBox)dgvDest.EditingControl;

            int selStartPos = editBox.SelectionStart;
            int selEndPos = selStartPos + editBox.SelectionLength;

            editBox.Text = editBox.Text.Substring(0, selStartPos) + cellSrc.Value.ToString() + editBox.Text.Substring(selEndPos);
            editBox.SelectionStart = selStartPos + cellSrc.Value.ToString().Length;
        }
        else
        {
            //Just override the entire cell
            cell.Value = cellSrc.Value;
        }
    }
}

【问题讨论】:

  • 您需要记住 dgv1 中的插入点还是总是替换整个单元格内容?另外:中断编辑会导致验证错误吗?
  • @TaW 两者,我在问题中添加了一个示例。 ;) 中断不是问题,我可以做一些事情,比如处理 dgv2 上的 onclick 事件,然后将焦点设置回 dgv1 选择单元格并再次开始编辑,然后将选择索引放在文本编辑中的最后一个已知位置盒子...我只是希望有一个更简单的方法。如果没有,我只会让它在右键单击按钮上工作......我只是希望我可以用左键单击按钮做同样的事情。
  • 我怀疑它可以做到,但我之前错了;-)
  • @TaW 可以的 ;)

标签: c# winforms datagridview double-click


【解决方案1】:

您可以将DataGridView 设为不可选择,也可以将其设为只读。然后当用户双击其单元格时,它不会从焦点控件中窃取焦点。

要使其只读,只需将其ReadOnly 属性设置为true。要使不可选择,您可以从DataGridView 和构造函数中派生,使不可选择:

SetStyle(ControlStyles.Selectable, false);

注意

由于SetStyle 受到保护,您不能在不受控制的情况下使用它。但是您可以使用反射来调用它。由于它是一种有用的方法,因此您可以创建一个扩展方法,就像我使用 here 模拟屏幕键盘的方法一样。然后你可以对所有控件使用它。这是我用于第二个DataGridView 的设置:

this.dataGridView2.SetStyle(ControlStyles.Selectable, false);
this.dataGridView2.ReadOnly = true;

这是我用来暴露SetStyle的扩展方法:

public static class Extensions
{
    public static void SetStyle(this Control control, ControlStyles flags, bool value)
    {
        Type type = control.GetType();
        BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Instance;
        MethodInfo method = type.GetMethod("SetStyle", bindingFlags);
        if (method != null)
        {
            object[] param = { flags, value };
            method.Invoke(control, param);
        }
    }
}

【讨论】:

    猜你喜欢
    • 2011-03-15
    • 2011-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-09
    • 1970-01-01
    • 1970-01-01
    • 2016-04-13
    相关资源
    最近更新 更多