C# 在子窗体中按Enter键可以强制我返回主窗体
在我描述问题之前,让我解释一下程序是什么样的: 我有一个程序,我使用一个窗口作为主机来显示所有子窗体。这个窗口(主面板窗体)有一个面板控件。我将一个子窗体附加到面板控件中以显示该子窗体,然后将其分离并附加另一个子窗体。通过这种方式,用户只能从我的应用程序中看到一个窗口,而不能从我的应用程序中看到多个窗口。主面板窗体具有一种机制,用于管理子窗体的附加/分离以及子窗体之间的通信 当程序启动时,主面板窗体将主菜单子窗体附加到其面板控件中。当用户从主菜单子窗体中选择菜单选项时,主菜单子窗体会告知主面板窗体用户已通过回调功能选择的选项。此时,主面板窗体将从面板控件分离主菜单子窗体(隐藏它,而不是销毁它),然后将与用户所选选项对应的子窗体附加到面板控件 除了附加/分离机制相当复杂之外,其他一切都正常工作。共谋不是问题所在。问题是,当用户点击子窗体中的Enter键时,程序会将用户踢回主面板窗体,而不是让子窗体处理Enter键。此问题仅在用户以前打开子窗体一次时发生。请记住,在我拆下子窗体后,我会隐藏子窗体,我不会破坏它。不知何故,这触发了错误 我可以通过在子窗体与面板控件分离时销毁它(然后在需要时重新创建它)来解决这个问题。但是我的应用程序要求当用户返回子表单时,子表单中的信息应该保持不变。实现这一点最简单的方法是隐藏子窗体,然后在需要再次显示时取消隐藏它 我目前正在通过捕获和丢弃ProcessCmdKey()事件处理程序中的密钥来解决此问题。但这似乎是一个黑客行为,并没有真正解决问题的根源。此外,如果子窗体需要对Enter键执行某些操作(例如尝试将Enter键转换为Tab键),我需要告诉ProcessCmdKey()不要对该子窗体执行此操作。奇怪的是,在这种情况下,我需要要求主面板窗体中的ProcessCmdKey()不要对子窗体执行此操作(而不是要求子窗体中的ProcessCmdKey()不要执行此操作)——这就是为什么我说这是一种攻击 以下是主面板形式的简化版本,我认为问题的根源可能是:C# 在子窗体中按Enter键可以强制我返回主窗体,c#,winforms,panel,enter,C#,Winforms,Panel,Enter,在我描述问题之前,让我解释一下程序是什么样的: 我有一个程序,我使用一个窗口作为主机来显示所有子窗体。这个窗口(主面板窗体)有一个面板控件。我将一个子窗体附加到面板控件中以显示该子窗体,然后将其分离并附加另一个子窗体。通过这种方式,用户只能从我的应用程序中看到一个窗口,而不能从我的应用程序中看到多个窗口。主面板窗体具有一种机制,用于管理子窗体的附加/分离以及子窗体之间的通信 当程序启动时,主面板窗体将主菜单子窗体附加到其面板控件中。当用户从主菜单子窗体中选择菜单选项时,主菜单子窗体会告知主面板窗
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics; // For using Debug.Assert().
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace TestEnterKeyProblem
{
// Constants related to calling back functions
// -------------------------------------------
public enum MainMenu_SelOpt : int
{
DlgBoxNormal = 1,
DlgBoxChgEnterToTab = 2
}
// Delegates for call-backs from this sub-form
// -------------------------------------------
// Call back function to communicate from the
// main-menu to this main panel.
public delegate void CallBackFuncFromMainMenu
(
MainMenu_SelOpt fMenuOptSelected
);
// Call back function to communicate from the
// dialog-box-normal to this main panel.
public delegate void CallBackFuncFromDlgBoxNormal();
// Call back function to communicate from the
// dialog-box-change-enter-to-tab to this main panel.
public delegate void CallBackFuncFromDlgBoxChgEnterToTab();
// Definition of frmMainPanel
// --------------------------
public partial class frmMainPanel : Form
{
// These flags tell us which sub-form is the active form
public enum ActiveFrm : int
{
Is_MainMenu = 31,
Is_DlgBoxNormal = 32,
Is_DlgBoxChgEnterToTab = 33
}
// Data members
//....This flag indicate which window in this application
//....has the input focus.
private ActiveFrm activeFrm = ActiveFrm.Is_MainMenu;
//....The following are the sub-forms that can be attached
//....to the main panel control of this object.
private frmMainMenu subfrmMainMenu = new frmMainMenu();
private frmDlgBoxNormal subfrmDlgBoxNormal = new frmDlgBoxNormal();
private frmDlgBoxChgEnterToTab subfrmDlgBoxChgEnterToTab = new frmDlgBoxChgEnterToTab();
// Class constructor
public frmMainPanel()
{
InitializeComponent();
this.activeFrm = ActiveFrm.Is_MainMenu;
}
// Event handlers
private void frmMainPanel_Load(object sender, EventArgs e)
{
// Attach the main-menu sub-form to the panel-control.
this.AttachMainMenuSubFormToPanelCtrl();
}
// Attach various sub-forms to the panel control in this form.
private void AttachMainMenuSubFormToPanelCtrl()
// Attach the main-menu sub-form to the panel control.
// Note: We don't detach the main menu sub-form. This means we only
// need to use this routine to attach the main menu sub-form
// only once. We detach all other sub-forms.
{
// Attach the main-menu sub-form to the panel.
this.subfrmMainMenu.TopLevel = false;
// Set it to false because we cannot add a top-control
// into another control (the main panel).
this.panelMain.Controls.Add( this.subfrmMainMenu );
// Tell the main menu sub-form which function to call back.
CallBackFuncFromMainMenu funcCallBackFromMainMenu =
new CallBackFuncFromMainMenu( this.OnCallBackFromMainMenu );
this.subfrmMainMenu.SetCallBackFunc( funcCallBackFromMainMenu );
// Now, we can activate the main menu.
this.subfrmMainMenu.Visible = true;
this.activeFrm = ActiveFrm.Is_MainMenu;
}
private void AttachDlgBoxNormalSubFrmToPanelCtrl()
// Attach the dialog-box-normal sub-form to the panel-control.
{
// Attach the dialog-box-normal sub-form to the panel.
this.subfrmDlgBoxNormal.TopLevel = false;
// Set it to false because we cannot add a top-control
// into another control (the main panel).
this.panelMain.Controls.Add( this.subfrmDlgBoxNormal );
// Tell the dialog-box-normal sub-form which function to call back.
CallBackFuncFromDlgBoxNormal funcCallBackFromDlgBoxNormal =
new CallBackFuncFromDlgBoxNormal( this.OnCallBackFromDlgBoxNormal );
this.subfrmDlgBoxNormal.SetCallBackFunc( funcCallBackFromDlgBoxNormal );
// Now, we can hide the main menu and show the
// dialog-box-normal sub-form.
this.subfrmMainMenu.Visible = false;
this.subfrmDlgBoxNormal.Visible = true;
this.activeFrm = ActiveFrm.Is_DlgBoxNormal;
}
private void AttachDlgBoxChgEnterToTabSubFrmToPanelCtrl()
// Attach the dialog-box-change-enter-to-tab sub-form to the
// panel-control.
{
// Attach the dialog-box-change-enter-to-tab sub-form to the panel.
this.subfrmDlgBoxChgEnterToTab.TopLevel = false;
// Set it to false because we cannot add a top-control
// into another control (the main panel).
this.panelMain.Controls.Add( this.subfrmDlgBoxChgEnterToTab );
// Tell the dialog-box-change-enter-to-tab sub-form which
// function to call back.
CallBackFuncFromDlgBoxChgEnterToTab funcCallBackFromDlgBoxChkEnterToTab =
new CallBackFuncFromDlgBoxChgEnterToTab( this.OnCallBackFromDlgBoxChgEnterToTab );
this.subfrmDlgBoxChgEnterToTab.SetCallBackFunc( funcCallBackFromDlgBoxChkEnterToTab );
// Now, we can hide the main menu and show the
// dialog-box-change-enter-to-tab sub-form.
this.subfrmMainMenu.Visible = false;
this.subfrmDlgBoxChgEnterToTab.Visible = true;
this.activeFrm = ActiveFrm.Is_DlgBoxChgEnterToTab;
}
// Call-back function
public void OnCallBackFromMainMenu
(
MainMenu_SelOpt fMenuOptSelected
)
// The main menu sub-form tells the main panel which
// menu option that the user has selected.
{
////////////////////////////////////////
if ( this.activeFrm != ActiveFrm.Is_MainMenu )
{
String sCurActiveForm = "N/A";
if ( this.activeFrm == ActiveFrm.Is_DlgBoxNormal ) sCurActiveForm = "Is_DlgBoxNormal";
else if ( this.activeFrm == ActiveFrm.Is_DlgBoxChgEnterToTab ) sCurActiveForm = "Is_DlgBoxChgEnterToTab";
String sCurMenuOptSelected = "N/A";
if ( fMenuOptSelected == MainMenu_SelOpt.DlgBoxNormal ) sCurMenuOptSelected = "DlgBoxNormal";
else if ( fMenuOptSelected == MainMenu_SelOpt.DlgBoxChgEnterToTab ) sCurMenuOptSelected = "DlgBoxChgEnterToTab";
String sDebugMsg =
String.Concat( "frmMainPanel.cs - OnCallBackFromMainMenu() : ",
"Active form is supposed to be 'Is_MainMenu'; but it is '", sCurActiveForm, "'. ",
"Please note that menu-option-selected is '", sCurMenuOptSelected, "'. ",
"This is an error." );
MessageBox.Show( sDebugMsg, "Assertion Error", MessageBoxButtons.OK, MessageBoxIcon.Error );
}
////////////////////////////////////////
Debug.Assert( fMenuOptSelected == MainMenu_SelOpt.DlgBoxNormal ||
fMenuOptSelected == MainMenu_SelOpt.DlgBoxChgEnterToTab );
if ( fMenuOptSelected == MainMenu_SelOpt.DlgBoxNormal ) this.AttachDlgBoxNormalSubFrmToPanelCtrl();
else if ( fMenuOptSelected == MainMenu_SelOpt.DlgBoxChgEnterToTab ) this.AttachDlgBoxChgEnterToTabSubFrmToPanelCtrl();
// Note: We don't detach the main menu sub-form from the
// main panel control.
}
public void OnCallBackFromDlgBoxNormal()
// The dialog-box-normal sub-form tells the main panel
// that the user is done.
{
Debug.Assert( this.activeFrm == ActiveFrm.Is_DlgBoxNormal );
// Detach the dialog-box-normal sub-form from the main panel
// control. We don't delete it. We keep it hidden.
this.subfrmDlgBoxNormal.Visible = false;
this.panelMain.Controls.Remove( this.subfrmDlgBoxNormal );
// Go back to the main menu.
this.subfrmMainMenu.Visible = true;
this.activeFrm = ActiveFrm.Is_MainMenu;
}
public void OnCallBackFromDlgBoxChgEnterToTab()
// The dialog-box-change-enter-to-tab sub-form tells the
// main panel that the user is done.
{
Debug.Assert( this.activeFrm == ActiveFrm.Is_DlgBoxChgEnterToTab );
// Detach the dialog-box-change-enter-to-tab sub-form from the
// main panel control. We don't delete it. We keep it hidden.
this.subfrmDlgBoxChgEnterToTab.Visible = false;
this.panelMain.Controls.Remove( this.subfrmDlgBoxChgEnterToTab );
// Go back to the main menu.
this.subfrmMainMenu.Visible = true;
this.activeFrm = ActiveFrm.Is_MainMenu;
}
}
}
当用户点击子窗体中的Enter键时(在之前打开子窗体一次之后),程序将以某种方式转到上面显示的主面板窗体中的OnCallBackFromMain菜单()(而不是允许子窗体处理Enter键,或返回子窗体的回调函数)
我试图附加示例程序的工作版本。但我不知道如何在这个论坛上做到这一点。如果你想试试这个示例程序,请告诉我,我会把它上传到一个公共FTP站点
我搞不懂这个。你能帮我修一下吗?提前谢谢
陈杰伦猜一猜。。。由于我没有看到表格的相关代码:
enter键是触发表单上的
按钮
单击事件。按钮的对话框结果
属性设置为除无
之外的其他属性谢谢。但是否,所有表单的AcceptButton均为(无)。程序中所有按钮的DialogResult均为None。若要了解问题的原因,请从此处下载程序工作版本的源代码的ZIP文件。这是一个简化的程序,只是为了说明问题。编译并构建它,运行它以查看主菜单。从主菜单中,选择要查看子窗体的链接中的任何一个,关闭子窗体,返回主菜单,再次选择相同的链接,查看相同的子窗体,然后按Enter键并查看错误消息。@JayChan无法使用此zip文件,缺少子目录(AssemblyInfo、Resources.resx等)中所有必需的文件很抱歉,最后一个ZIP文件缺少“属性”子文件夹。我上传了一个新的ZIP文件,其中包括丢失的“属性”子文件夹和所有其他文件。你可以从这里下载。谢谢你帮我。