I’m currently working on a hobby project where I’m displaying a list of files in a way similar to the “details” view of Windows Explorer. For various reasons I’m using a DataGridView instead of a ListView, and while configuring the DataGridView to look like a ListView wasn’t much of a problem, there’s one thing that got on my nerves, which is the behavior of textbox cells in edit mode: It is much too easy to leave the edit mode accidentally, simply by pressing the cursor keys at the wrong time. For example when the text caret is positioned behind the last character of the textbox cell content, and you press the right arrow key: the focus then moves to the next cell. There are certainly use cases for this behavior, but for my purposes I wanted the text caret to be “captured” inside the textbox in edit mode until you press Enter, Tab or Escape (or use the mouse to click another cell).
The nice thing about the DataGridView is that you can tweak it a lot by deriving from existing classes for cells, columns and editing controls, overriding certain methods. In my case I suspected that the DataGridViewTextBoxEditingControl (derived from TextBox) would contain special code to determine when the cell should leave edit mode. As I didn’t know what to search the documentation for (and I was too impatient to read it completely, to be honest), I fired up Lutz Roeder’s Reflector and took a look at the decompiled code of the class members. With the option “Show Inherited Members” switched off it took me only a couple of seconds to come across the code of the EditingControlWantsInputKey method which looked exactly like what I was expecting (lucky me: it was the 4th member in the list ;-).
So here are the steps to change the behavior of the editing control:
First derive a class from DataGridViewTextBoxEditingControl and override the EditingControlWantsInputKey method:
public class CustomDataGridViewTextBoxEditingControl
: DataGridViewTextBoxEditingControl
{
public override bool EditingControlWantsInputKey( Keys keyData, bool dataGridViewWantsInputKey )
{
switch (keyData & Keys.KeyCode)
{
case Keys.Prior:
case Keys.Next:
case Keys.End:
case Keys.Home:
case Keys.Left:
case Keys.Up:
case Keys.Right:
case Keys.Down:
case Keys.Delete:
return true;
}
return base.EditingControlWantsInputKey( keyData, dataGridViewWantsInputKey );
}
}
Then derive a class from DataGridViewTextBoxCell and override the EditType property to use the customized editing control:
public class CustomDataGridViewTextBoxCell
: DataGridViewTextBoxCell
{
public override Type EditType
{
get { return typeof( CustomDataGridViewTextBoxEditingControl ); }
}
}
Finally derive a class from DataGridViewTextBoxColumn to be able to use the new cell type.
public class CustomDataGridViewTextBoxColumn
: DataGridViewColumn
{
public CustomDataGridViewTextBoxColumn()
: base( new CustomDataGridViewTextBoxCell() )
{
}
}
You can now use the new column type in your code as a replacement of the stock DataGridViewTextBoxColumn (the new type appears in the drop down lists for column types in the designer dialogs of the DataGridView control).
A demo project is available here, showing a DataGridView with a normal DataGridViewTextBoxColumn and the CustomDataGridViewTextBoxColumn next to each other, so you can compare the different behaviors.
本文介绍了一种方法,通过自定义DataGridView编辑控制,优化文件显示列表的行为,使其在编辑模式下更容易捕获文本光标,直到按下Enter键、Tab键、Esc键或点击其他单元格才退出编辑模式。

被折叠的 条评论
为什么被折叠?



