[英]KeyUp event not firing on DataGrid
無法理解為什么不是,這是示例代碼:
public Form1()
{
InitializeComponent();
//Create DataGrid
DataGrid dg = new DataGrid();
dg.Parent = this;
dg.Location = new Point(10, 10);
dg.Size = new System.Drawing.Size(300, 200);
//Create list of people
List<Person> people = MethodThatFetchesPeople();
//Bind list
BindingList<Person> bl_people = new BindingList<Person>(people);
dg.DataSource = bl_people;
//Format grid
dg.TableStyles.Clear();
DataGridTableStyle dgts = new DataGridTableStyle();
dgts.MappingName = bl_people.GetType().Name;
dgts.ReadOnly = true;
DataGridTextBoxColumn col_name = new DataGridTextBoxColumn();
col_name.MappingName = "Name";
col_name.HeaderText = "Name";
dgts.GridColumnStyles.Add(col_name);
DataGridTextBoxColumn col_height = new DataGridTextBoxColumn();
col_height.MappingName = "Height";
col_height.HeaderText = "Height (cm)";
dgts.GridColumnStyles.Add(col_height);
dg.TableStyles.Add(dgts);
//Subscribe events
col_name.TextBox.KeyDown += new KeyEventHandler(TextBox_KeyDown);
col_name.TextBox.KeyUp += new KeyEventHandler(TextBox_KeyUp);
}
事件處理方法:
void TextBox_KeyUp(object sender, KeyEventArgs e)
{
//Do something on keyup
Debug.WriteLine("Keyup!");
}
void TextBox_KeyDown(object sender, KeyEventArgs e)
{
//Do something on keydown
Debug.WriteLine("Keydown!");
}
}
按下Name列中的值后, DataGridTextBoxColumn獲得焦點。 然后每當我按下一個鍵時, KeyDown事件就會被觸發,但KeyUp事件沒有任何反應,即使未訂閱KeyDown事件也是如此。
我真的只需要KeyUp事件,KeyDown不符合我的目的。 我不能只是切換到DataGridView,因為此代碼將與緊湊框架一起使用:(
我怎么解決這個問題?
我已經看到這種情況特別發生在Windows窗體/桌面應用程序上,但在此處發布,以防它在移動設備上也適用。
DataGrid控件習慣於“吞咽”某些鍵盤事件。 它在內部處理它們(我相信它們由各個網格單元處理)並且它們不會“冒泡”到其他控件,因為事件已被消耗。
有兩種不同的方法可以做到這一點。 基本上,您需要設置表單以在事件到達DataGrid之前攔截事件,然后預處理並決定是否還要將事件傳遞給DataGrid。
要在應用程序內創建“通用過濾器”,請執行以下操作。 如果您遵循調度程序模式並且可能需要將鍵擊路由到許多不同控件之一,則可以執行此操作:
在Form的構造函數中:
this.KeyPreview = true;
Application.AddMessageFilter(this);
在表單中覆蓋此方法。 如果此方法返回“true”,則將消耗該事件,並且不會將該事件分派給任何其他控件。 如果此方法返回“false”,則事件將正常地通過所有控件。
// This is the ONLY way to prevent buttons, checkboxes, and datagrids from processing the UP and DOWN arrows
const int WM_KEYDOWN = 0x100;
const int WM_KEYUP = 0x101;
public bool PreFilterMessage(ref Message m)
{
try
{
if (m.Msg == WM_KEYDOWN)
// handle event here and return true
else if (m.Msg == WM_KEYUP)
// handle event here and return true
}
}
catch
{
return false;
}
return false;
}
我在大約10年前編寫/計算了所有這些,所以也許有其他/更好的方法來做到這一點,但這對我有用,我不必創建任何控件的自定義實現來使其工作。
我在MSDN文章中找到的另一種技術。 它是為VB編寫的,但應該很容易翻譯成C#:
https://support2.microsoft.com/default.aspx?scid=kb;en-us;320583&Product=vbNET
這里的基本前提是ProcessCmdKey
DataGrid並覆蓋ProcessCmdKey
方法。
這篇MSDN文章建議CF中的鍵盤事件處理並不容易,但它可能提供一個解決方案。 我沒有讀完這一切。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.