如何正确实现处理助记符的自定义控件?

时间:2010-10-13 16:41:12

标签: .net winforms user-interface custom-controls

我在WinForms中实现自定义控件。此控件需要响应助记符,并且助记符需要将下一个控件集中在Tab键顺序中 - 就像Label控件那样。

ProcessMnemonic方法显然是要覆盖的方法。但是,看看Label控件是如何做的,作为参考,表明它在很大程度上依赖于WinForms内部:

  • 要检查是否可以响应助记符,Label会使用内部CanProcessMnemonic方法。
  • 该方法请求UIPermission,然后使用一堆内部类和调用来验证焦点是否可以更改。
  • 使用内部“ParentInternal”字段更改焦点。

我没想到对助记符的回应可能如此复杂。如果我省略所有那些内部调用并且只使用非内部Parent,它似乎有效,但它让我想知道:肯定代码不存在,所以我的天真实现必须缺少某些东西?

这是Label的真实代码,由我调整以便于阅读:

[UIPermission(SecurityAction.LinkDemand, Window=UIPermissionWindow.AllWindows)]
protected internal override bool ProcessMnemonic(char charCode)
{
    if ((!UseMnemonic || !IsMnemonic(charCode, Text)) || !CanProcessMnemonic() /*internal*/)
        return false;

    if (ParentInternal != null) /* internal */
    {
        IntSecurity.ModifyFocus.Assert(); /* internal */
        try
        {
            if (ParentInternal.SelectNextControl(this, true, false, true, false) && !ParentInternal.ContainsFocus)
                ParentInternal.Focus();
        }
        finally
        {
            CodeAccessPermission.RevertAssert();
        }
    }
    return true;
}

这是我对它的“天真”改写:

protected override bool ProcessMnemonic(char charCode)
{
    if ((!UseMnemonic || !IsMnemonic(charCode, Text)) || !Enabled || !Visible)
        return false;

    if (Parent != null)
        if (Parent.SelectNextControl(this, true, false, true, false) && !Parent.ContainsFocus)
            Parent.Focus();

    return true;
}

一个显而易见的区别是CanProcessMnemonic递归地检查父代,而我的代码却没有,因为这种方法是莫名其妙的内部...

0 个答案:

没有答案