Метод, чтобы определить, применяются ли значения клавиши Mnemonic/Accelerator к элементу управления?

У меня есть приложение (.net framework 4, vb.net), которое изначально было приложением VB6. Чтобы имитировать части старого поведения управления вкладками, я реализую клавиши быстрого доступа, которые позволяют вам переключаться на другую вкладку. Пример — TabControl с 5 вкладками. - Вкладка 2 имеет метку &Data (ускоритель alt-d) с текстовым полем - Пользователь выбрал вкладку 1 и нажимает alt-d, что приводит к тому, что элемент управления вкладкой выбирает вкладку 2 и устанавливает фокус на соответствующее текстовое поле.

Я написал некоторый код, который ищет вкладку, содержащую элемент управления (я делаю это, переопределяя ProcessMnemonic), и просто просматриваю вкладки (начиная с выбранной), и если я нахожу совпадение, я выбираю вкладку, а затем разрешаю системе для обработки мнемоники, вызвав "MyBase.ProcessMnemonic(charCode)".

Но моя проблема связана с вызовом Control.IsMnemonic. Поскольку вы передаете только «текст» элемента управления, любой элемент управления, который содержит & в свойстве text, может привести к совпадению.

Например, myTextbox.Text = "здесь и друг" заставит Alt-F установить фокус на этом поле.

Я могу явно проверить, является ли тип элемента управления меткой... но тогда мне также нужны групповые поля и... что еще? Кнопки я должен также разрешить мнемоники...

Вот некоторый код (обратите внимание, что я не включил итерацию табуляции, поскольку она не казалась уместной);

Private Function IsMnemonicInThisContainer(charCode As Char, controlContainer As System.Windows.Forms.Control.ControlCollection) As Boolean

    For Each ctrl As Control In controlContainer

        If Control.IsMnemonic(charCode, ctrl.Text) Then

            If ControlIsAlive(ctrl) Then
                Return True
            End If

        ElseIf ctrl.HasChildren Then

            If ControlIsAlive(ctrl) AndAlso IsMnemonicInThisContainer(charCode, ctrl.Controls) Then
                Return True
            End If

        End If
    Next

    Return False

End Function

Private Function ControlIsAlive(ctrl As Control) As Boolean

    ' In a TABPAGE that is not selected, the controls all appear to be visible = FALSE,
    ' because they aren't actually "visible" - HOWEVER... the control itself may be expecting
    ' to be visible (once it's tab is shown)... so this call to GetStateMethodInfo which I grabbed from
    ' http://stackoverflow.com/questions/3351371/using-control-visible-returns-false-if-its-on-a-tab-page-that-is-not-selected
    ' is the solution I needed. 
    ' Instead of walking the tree though I am going to "check containers" as I drop into them... if they are not enabled/visible
    ' then I'm not going to go any deeper

    ' Is control enabled and going to be shown?  (calling ctrl.visible allows us to bypass the other call if we can!)
    Return (ctrl.Enabled AndAlso (ctrl.Visible OrElse CBool(GetStateMethodInfo.Invoke(ctrl, New Object() {2}))))

End Function

Думаю, я мог бы сделать что-то вроде...

Если Typeof ctrl - это Label orelse Typeof ctrl - это групповое поле (и т.д...)...

Но свойство (или метод) для определения этого было бы здорово. Любые идеи?

Спасибо! Крис Вудрафф


person Chris Woodruff    schedule 09.11.2011    source источник
comment
Итак... почему вы не позволяете фреймворку winforms обрабатывать все это за вас?   -  person Sam Axe    schedule 10.11.2011
comment
Разве не было бы наоборот: если это НЕ TextBox, то все в порядке?   -  person LarsTech    schedule 10.11.2011
comment
Вы относитесь к этому так, как будто я не могу это контролировать. Это заблуждение, конечно. Именно вы устанавливаете свойства элемента управления. Если ProcessMnemonic() выбирает неправильный элемент управления, то вы присвоили этому элементу управления неверное свойство Text. Если это были не вы, то парень, который это сделал, находится в соседней кабинке.   -  person Hans Passant    schedule 10.11.2011
comment
Бу - я не уверен, как это может быть? В .net элемент управления вкладками не распознает мнемонику другой вкладки. Имеет смысл то, как все работает, просто здесь нет того поведения, которое мне нужно.   -  person Chris Woodruff    schedule 10.11.2011
comment
Извините, меня отключили... LarsTech - Проблема в других элементах управления, выпадающем списке, списке и т. д.... все они имеют свойства TEXT, которые также могут вызывать эту проблему. Ганс, я не понимаю. Параметр TEXT объекта IsMnemonic представляет собой просто STRING. Я бы подумал, что MS сделает myControl.IsMnemonic(charcode), но это не так. Это статический сигнал Control.IsMnemonic(charcode, string)   -  person Chris Woodruff    schedule 10.11.2011