阻止 datagridview 对象被点击和窃取焦点的最佳方法
Best way to stop a datagridview object from getting clicked and stealing focus
我的表单上有两个数据网格视图。我有一个 (dgv1) 用于编辑数据,另一个 (dgv2) 仅用于查看(捕获点击操作)。例如,我可能正在编辑 dgv1 中的一个单元格(文本),需要双击 dgv2 中的一行以将内容放入 dgv1(类似于快速 copy/paste)。目前我必须在 dgv2 上使用鼠标右键双击事件,因为如果在任何时候我左键单击或左键双击,焦点将从 dgv1 移动到 dgv2 并停止编辑我正在处理的 dgv1 单元格。
我想看看是否可以通过用鼠标左键双击 dgv2 来完成我正在做的事情?
我唯一能想到的就是尝试找到一种禁用鼠标左键单击事件的方法,但我希望基本上只是让它 "not respond" 就像双击鼠标右键单击时那样cell/row.
想法?
编辑: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;
}
}
}
您可以将 DataGridView
设为不可选择,也可以设为只读。然后当用户双击它的单元格时,它不会从获得焦点的控件中窃取焦点。
要使其为只读,只需将其 ReadOnly
属性 设置为 true 即可。要使不可选择,您可以从 DataGridView
派生,并在构造函数中,使不可选择:
SetStyle(ControlStyles.Selectable, false);
备注
由于 SetStyle
受到保护,您不能在您无法控制的情况下使用它。但是您可以使用反射来调用它。由于它是一种有用的方法,您可以创建一个扩展方法,就像我使用 模拟屏幕键盘的方法一样。然后你可以对所有控件使用它。这是我用于第二个 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);
}
}
}
我的表单上有两个数据网格视图。我有一个 (dgv1) 用于编辑数据,另一个 (dgv2) 仅用于查看(捕获点击操作)。例如,我可能正在编辑 dgv1 中的一个单元格(文本),需要双击 dgv2 中的一行以将内容放入 dgv1(类似于快速 copy/paste)。目前我必须在 dgv2 上使用鼠标右键双击事件,因为如果在任何时候我左键单击或左键双击,焦点将从 dgv1 移动到 dgv2 并停止编辑我正在处理的 dgv1 单元格。
我想看看是否可以通过用鼠标左键双击 dgv2 来完成我正在做的事情?
我唯一能想到的就是尝试找到一种禁用鼠标左键单击事件的方法,但我希望基本上只是让它 "not respond" 就像双击鼠标右键单击时那样cell/row.
想法?
编辑: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;
}
}
}
您可以将 DataGridView
设为不可选择,也可以设为只读。然后当用户双击它的单元格时,它不会从获得焦点的控件中窃取焦点。
要使其为只读,只需将其 ReadOnly
属性 设置为 true 即可。要使不可选择,您可以从 DataGridView
派生,并在构造函数中,使不可选择:
SetStyle(ControlStyles.Selectable, false);
备注
由于 SetStyle
受到保护,您不能在您无法控制的情况下使用它。但是您可以使用反射来调用它。由于它是一种有用的方法,您可以创建一个扩展方法,就像我使用 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);
}
}
}