在我描述问题之前,让我解释一下程序是什么样的:
我有一个程序,我使用一个窗口作为主机来显示所有子表单。这一个窗口(主面板形式)有一个Panel控件。我将一个子表单附加到面板控件中以显示子表单,然后将其分离并附加另一个子表单。通过这种方式,用户只能从我的应用程序中看到一个窗口,而不是从我的应用程序中看到多个窗口。主面板形式有一种机制来管理子表单的附加/分离以及子表单之间的通信。
当程序启动时,main-panel-form将主菜单子窗体附加到其Panel控件中。当用户从主菜单子表单中选择菜单选项时,主菜单子表单告诉主面板表单用户通过回叫功能选择的选项。此时,主面板表单将从Panel控件中分离主菜单子表单(隐藏它,而不是销毁它),然后将对应于用户所选选项的子表单附加到Panel控件。 / p>
除了附加/分离机制非常复杂之外,一切正常。共谋不是问题。问题是,当用户点击子表单中的Enter键时,程序会将用户踢回主面板表单,而不是让子表单处理Enter键。只有在用户之前打开子表单时才会出现此问题。请记住,在我分离子表单后,我保持子表单隐藏,我不会破坏它。不知何故,这会触发错误。
我可以通过在子窗体从Panel控件分离时销毁子窗体来解决这个问题(然后在需要时重新创建它)。但是我的应用程序要求当用户返回子表单时,子表单中的信息应保留在原位。完成此操作的最简单方法是隐藏子表单,然后在需要再次显示时取消隐藏它。
我目前正在通过在ProcessCmdKey()事件处理程序中捕获和丢弃密钥来解决此问题。但这似乎是一个黑客,并没有真正解决问题的根源。此外,如果子表单需要对Enter键执行某些操作(例如尝试将Enter键转换为Tab键),我将需要告诉ProcessCmdKey()不要为该子表单执行此操作。奇怪的是,在这种情况下,我需要在main-panel-form中询问ProcessCmdKey()不要为子表单执行此操作(而不是要求子表单中的ProcessCmdKey()不要这样做) - 这就是为什么我说这是一个黑客。
以下是主面板形式的简化版本,我相信问题的根源可能是:
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键时(在子表单之前打开一次之后),程序将以某种方式转到上面显示的主面板表单中的OnCallBackFromMainMenu()(而不是允许用于处理Enter键的子表单,或返回子表单的回调函数。
我尝试附加示例程序的工作版本。但我不知道如何在这个论坛上做到这一点。如果您想尝试示例程序,请告诉我,我会将其上传到公共FTP站点。
我无法弄清楚这一点。你能帮我解决这个问题吗?提前谢谢。
杰伊陈答案 0 :(得分:0)
猜测...因为我没有看到表格的相关代码:
回车键会触发表单上的#cf {
position: relative;
height: 281px;
width: 450px;
margin: 0 auto;
}
#cf img {
position: absolute;
left: 0;
-webkit-transition: opacity 1s ease-in-out;
-moz-transition: opacity 1s ease-in-out;
-o-transition: opacity 1s ease-in-out;
transition: opacity 1s ease-in-out;
}
@keyframes cf3FadeInOut {
0% {
opacity: 1;
}
45% {
opacity: 1;
}
55% {
opacity: 0;
}
100% {
opacity: 0;
}
}
#cf3 img.top {
animation-name: cf3FadeInOut;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
animation-duration: 10s;
animation-direction: alternate;
}
Click事件。该按钮的Button
属性设置为DialogResult
以外的其他属性。