在子表单中按Enter键可以强制我回到主表单

时间:2017-04-05 16:00:46

标签: c# winforms panel enter

在我描述问题之前,让我解释一下程序是什么样的:

我有一个程序,我使用一个窗口作为主机来显示所有子表单。这一个窗口(主面板形式)有一个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站点。

我无法弄清楚这一点。你能帮我解决这个问题吗?提前谢谢。

杰伊陈

1 个答案:

答案 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以外的其他属性。