[英]C# focus in forms and arrow keys
我想為游戲做一個地圖編輯器。 它是一個具有Windows Forms UI(例如,propertyGrid可以編輯對象的屬性)的程序,但是它也具有一個在其上繪制地圖的面板。
我想要的是:
當焦點位於帶有地圖的面板上時,我想使用鍵盤來移動地圖(箭頭鍵),添加對象(數字鍵)等。當焦點不在此面板上時,我希望按鈕可以用作在Windows窗體中正常-允許在控件之間制表符等
我的表格如下所示:
它具有一個ToolStripControl,它具有一個menuStrip(用於主菜單)和一個statusStrip(用於狀態欄)。 在表單(或toolstripcontrol)的中間,將SplitControl停靠在其中(具有兩個面板)(dock = fill)。 面板1具有PanelMap-一個顯示地圖的面板,面板2具有所有其他內容,例如propertygrid,tabcontrol,按鈕等。
我將窗體的KeyPreview設置為true,並在窗體的keydown事件處理程序中處理鍵盤事件。
現在,發生的事情是,如果我將焦點分配給PanelMap,則下次按下箭頭鍵時,將不會觸發KeyDown事件。 沒有一個! 偶數形式應該處理所有事件,因為它具有“ KeyPreview”,它甚至不會觸發。 當我按箭頭時,PanelMap失去對SplitControl的關注。
好的,我想,也許PanelMap不應該具有焦點,讓我們將焦點賦予SplitControl(如果我在有焦點的情況下按箭頭鍵,則可以處理它,因此它不會繼續前進)。 但是,如果在SplitControl內部的某個文本框之類的東西具有焦點,則SplitControl無法獲得焦點。 .Focus()不會執行任何操作-焦點仍然保留在擁有該控件的控件中!
為什么行為如此奇怪? 當面板具有焦點並按下箭頭鍵時,為什么Form的KeyDown不會觸發? 為什么即使CanFocus = true,當我調用.Focus()時,SplitControl也不會集中精力?
最終,我如何實現自己想要的? 有辦法嗎?
我認為在事件到達導航之前,您正在碰擊小部件進行擊鍵。 我遇到了這個問題,並這樣做:
private void RemoveCursorNavigation(Control.ControlCollection controls)
{
foreach(Control ctrl in controls)
{
ctrl.PreviewKeyDown += new PreviewKeyDownEventHandler(MainWin_PreviewKeyDown);
RemoveCursorNavigation(ctrl.Controls);
}
}
我在主窗體的Load處理程序中調用此函數,如下所示:
RemoveCursorNavigation(this.Controls);
在您的PreviewKeyDown處理程序中,您需要執行以下操作:
public void MainWin_PreviewKeyDown(Object sender, PreviewKeyDownEventArgs e)
{
switch(e.KeyCode)
{
case Keys.Up:
case Keys.Down:
case Keys.Left:
case Keys.Right:
e.IsInputKey = true;
break;
default:
break;
}
}
e.IsInputKey = true;
告訴外界您已使用此事件,並且不希望它在其他任何地方使用。
現在,您可以在擊鍵之前看到它們,並且不會從光標鍵之間進行導航。
我找到了這樣的答案:
我制作了一個隱藏在面板下的文本框(但已啟用且可見)。 當我想“鎖定” PanelMap的焦點時,將給該文本框以焦點。 即使使用e.suppress = true,它也具有onkeydown,因此文本框永遠不會受到任何擊鍵來影響它。
粗略的解決方法,但可以解決問題...典型的M $業務...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.