【问题标题】:winforms textbox validating event handlers stopped functioningwinforms 文本框验证事件处理程序停止运行
【发布时间】:2011-04-14 16:15:59
【问题描述】:

我有一个正在使用 VS2010 开发的 winforms 应用程序。 UI 由一个包含七个文本框的 tableLayoutPanel 组成。我安排了文本框的 Tab 键顺序,以引导用户完成逻辑数据输入进程。每个文本框都有一个 _Leave 事件、一个 _Validating 事件和一个 _Validated 事件。我还为表单添加了一个 _KeyDown 事件,以使 Enter 键的行为类似于 Tab 键。

    private void Form1_KeyDown( object sender, KeyEventArgs e )
    {
        if (e.KeyCode == Keys.Enter)
        {
            GetNextControl( ActiveControl, true ).Focus();
        }
       e.Handled = true;
    }

一开始一切都很好,每个文本框和事件都按预期运行。

然后我在表单中添加了一个列表框,用于用户可以像以前一样在表单中手动输入数据的用例,或者在列表框中突出显示一行预先设置的数据并按下按钮以使数据转移到文本框。

但是,无论使用何种数据输入方法,现在表单上的几个框都不会触发 _Validating 事件。触发了文本框的 _Leave 事件,但是当我单步执行代码时,我发现 _Leave 处理程序中调用的 ContainerControl.Validate() 方法不再导致分支到 _Validating(或 _Validated)事件处理程序。然而,其他文本框仍然像以前一样正常工作。我检查了工作文本框和非工作文本框,并且看不出属性上的差异。我什至删除了一个损坏的文本框并将一个工作文本框复制并重组到相同的物理位置。运气不好!

是否有禁止在一个表单上混合控件的规则?还是有某种已知问题?

我应该在这里补充一点,我没有使用绑定,而是在文本框中的字符串之间转换和解析数据。此逻辑分布在每个文本框的 _Validating 和 _Validated 事件之间。

好的,这里有更多信息:我通过在每个处理程序的开头和结尾放置 Trace 输出来检测事件处理程序。虽然没有什么可以作为解决方案跳出来,但我发现了一些有趣的事情。 _KeyDown 处理程序中的跟踪语句略有不同,因为我想看看 KeyCode 测试何时为真。您可以看到,此跟踪将在一行中生成所有输出...

   private void Form1_KeyDown( object sender, KeyEventArgs e )
    {
        Trace.Write( "%%% _KeyDown entered -- " );
        if (e.KeyCode == Keys.Enter)
        {
            GetNextControl( ActiveControl, true ).Focus();
            Trace.Write( "Enter key processing -- " );
        }
        Trace.WriteLine( " exiting" );
       e.Handled = true;
    }

那么发生了什么?如果您知道用户首先输入一个 3 个字符的单词,然后按 Enter,然后是一个两个字符的单词,然后 Enter,然后是一个 4 位数字,然后 Enter,则更有意义。这是成绩单,附有括号内的注释:

System.Core.dll 中发生了“System.PlatformNotSupportedException”类型的第一次机会异常

[用户输入三个字符并回车]

%%% _KeyDown 进入 -- 退出
%%% _KeyDown 已输入 -- 正在退出
%%% _KeyDown 已输入 -- 正在退出
%%% _KeyDown 输入 -- %%% longTkrTB _Leave 输入
[哇,这是什么? 离开已在KeyDown中间开始。]

%%% longTkrTB _离开调用 _Validating
%%% longTkrTB _验证输入
System.Core.dll 中出现“System.PlatformNotSupportedException”类型的第一次机会异常
System.Core.dll 中出现“System.PlatformNotSupportedException”类型的第一次机会异常
%%% longTkrTB _Validating 退出
%%% longTkrTB _已输入验证
%%% longTkrTB _Validated 退出

[现在进行其余的 KeyDown 处理。有谁知道这些事件是否是多线程的?]

进入关键处理——退出

[OK,第一个文本框已成功处理。到第二个,2 个字符 + Enter。]

%%% _KeyDown 进入 -- 退出
%%% _KeyDown 已输入 -- 正在退出
%%% _KeyDown 输入 -- %%% shortTkrTB _Leave 输入
[和以前一样,Leave 和验证过程会中断 KeyDown 处理吗?]

%%% shortTkrTB _离开调用 _Validating
%%% shortTkrTB _验证输入
%%% shortTkrTB _Validating 退出
%%% shortTkrTB _已验证输入
%%% shortTkrTB _Validated 退出
输入键处理 -- 退出
[KeyDown 处理的剩余部分用于第二个文本框输入键。第二个文本框已成功结束。开始第三个文本框中的 4 位数字。]

%%% _KeyDown 进入 -- 退出
%%% _KeyDown 已输入 -- 正在退出
%%% _KeyDown 已输入 -- 正在退出
%%% _KeyDown 已输入 -- 正在退出
[现在按 Enter 键,事情开始变得混乱。]

%%% _KeyDown 已输入 -- 线程 '' (0x2dc) 已退出,代码为 0 (0x0)。
步入:跳过没有符号 'System.Diagnostics.Trace.WriteLine' 的方法
[为什么我们之前没有看到此消息?]

%%% longVolTB _离开输入
[好的,预期的...]

步入:跳过不带符号“System.Windows.Forms.Control.Focused.get”的方法
步入:跳过没有符号“System.Windows.Forms.Control.Focused.get”的方法
步入:跳过没有符号“Harpswell.CreatePair.PairRec.IsDummyPair.get”的方法
步入:跳过没有符号“System.Windows.Forms.Control.Focused.get”的方法
步入:跳过没有符号“System.Windows.Forms.Control.CaptureInternal.get”的方法
步入:跳过没有符号“System.Windows.Forms.Control.Focused.get”的方法
步入:跳过没有符号“System.Windows.Forms.Control.Focused.get”的方法
步入:跳过没有符号“System.Windows.Forms.Control.Focused.get”的方法
步入:跳过没有符号'System.Diagnostics.Trace.WriteLine'的方法

[嗯!这是其他文本框没有发生的大量处理(除非消息已备份并且刚刚发布。如果是这样,为什么我们看不到更多的“Trace.WriteLine”消息?)] em>

%%% longVolTB _Leave 调用 _Validating
[这里是我们应该输入验证逻辑的地方...]

步入:跳过没有符号“System.Windows.Forms.ContainerControl.Validate”的方法
步入:跳过不带符号“System.Windows.Forms.ContainerControl.UpdateFocusedControl”的方法
步入:跳过不带符号“System.Windows.Forms.ContainerControl.AssignActiveControlInternal”的方法
步入:跳过不带符号“System.Windows.Forms.ContainerControl.ActivateControlInternal”的方法
步入:跳过不带符号“System.Windows.Forms.Control.WmSetFocus”的方法
步入:跳过没有符号“System.Windows.Forms.Control.WndProc”的方法
步入:跳过不带符号“System.Windows.Forms.TextBoxBase.WndProc”的方法
步入:跳过没有符号“System.Windows.Forms.NativeWindow.DebuggableCallback”的方法
步入:跳过没有符号“System.Windows.Forms.Control.FocusInternal”的方法
步入:跳过没有符号“System.Diagnostics.Trace.Write”的方法
进入关键处理——步入:不带符号'System.Diagnostics.Trace.WriteLine'的单步方法

退出
[这是什么? KeyDown 处理程序的尾部!]

步入:跳过不带符号“System.Windows.Forms.KeyEventArgs.Handled.set”的方法
步入:跳过不带符号“System.Windows.Forms.Control.OnKeyDown”的方法
步入:跳过没有符号“System.Windows.Forms.Control.ProcessKeyEventArgs”的方法
步入:跳过没有符号“System.Windows.Forms.Form.ProcessKeyPreview”的方法
步入:跳过没有符号“System.Windows.Forms.Control.ProcessKeyMessage”的方法
步入:跳过没有符号“System.Windows.Forms.Control.WndProc”的方法
步入:跳过不带符号“System.Windows.Forms.TextBoxBase.WndProc”的方法
步入:跳过没有符号“System.Windows.Forms.NativeWindow.DebuggableCallback”的方法
步入:跳过不带符号的方法 'System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop'
线程 '' (0x15f0) 已退出,代码为 0 (0x0)。
线程 '' (0xc20) 已退出,代码为 0 (0x0)。
线程 '' (0x11b4) 以代码 0 (0x0) 退出。

[等]

【问题讨论】:

  • 另外,为了保险起见,我在开始出现问题后为每个文本框添加了 CausesValidation = true 语句,但这并没有改变任何行为。
  • 我可能会将当前线程上下文的 ID 添加到我的日志中

标签: c# winforms textbox event-handling


【解决方案1】:

表单具有控制顺序序列,例如通过字段处理您的选项卡。如果您添加了列表框和标签来描述备选方案,那可能会弄乱您认为的制表顺序...表格流程面板中的制表键实际上可以工作...它只是从面板的文本框到标签或列表框。

我会检查控件的跳格顺序以确保它们的顺序正确。

【讨论】:

  • 标签仍然按照原来的顺序排列在文本框中。我应该补充一点,我强迫我的 formx.designer.cs 重建,以防它出现问题。我可以看到设计器中添加的事件,就像以前一切正常时一样......
  • 为了确定并遵循您的建议,我还检查了每个控件并重新编号了选项卡,但行为仍然没有变化。 :(
【解决方案2】:

我发现了这个问题,所以我把它贴在这里,以防其他人有这个问题。我不确定这是一个解决方案还是一个黑客,但是......

我的表单上有大量控件,在包含标签的文本框、数据输入文本框、按钮,当然还有列表框和 tableLayoutPanel 之间。我错误地认为那些包含静态信息(如按钮、图例等)的控件可以使用属性“CausesValidation=false”进行标记。这个错误在我看来仍然是合理的。

一旦我将每个带有“CausesValidation”属性的控件都更改为“true”,我的问题就消失了。显然,一些控件的 CausesValidation 属性正在启动到我的数据输入控件上,尽管我在 form1.designer.cs 代码隐藏中没有发现任何问题的迹象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-15
    • 1970-01-01
    • 2021-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多