示例#1
0
        private void ChangeFocus(DependencyObject focus, int timestamp)
        {
            DependencyObject o = null;

            if (focus != _focus)
            {
                // Update the critical pieces of data.
                DependencyObject oldFocus = _focus;
                _focus           = focus;
                _focusRootVisual = InputElement.GetRootVisual(focus);

                using (Dispatcher.DisableProcessing()) // Disable reentrancy due to locks taken
                {
                    // Adjust the handlers we use to track everything.
                    if (oldFocus != null)
                    {
                        o = oldFocus;
                        if (InputElement.IsUIElement(o))
                        {
                            ((UIElement)o).IsEnabledChanged -= _isEnabledChangedEventHandler;
                            ((UIElement)o).IsVisibleChanged -= _isVisibleChangedEventHandler;
                            ((UIElement)o).FocusableChanged -= _focusableChangedEventHandler;
                        }
                        else if (InputElement.IsContentElement(o))
                        {
                            ((ContentElement)o).IsEnabledChanged -= _isEnabledChangedEventHandler;
                            // NOTE: there is no IsVisible property for ContentElements.
                            ((ContentElement)o).FocusableChanged -= _focusableChangedEventHandler;
                        }
                        else
                        {
                            ((UIElement3D)o).IsEnabledChanged -= _isEnabledChangedEventHandler;
                            ((UIElement3D)o).IsVisibleChanged -= _isVisibleChangedEventHandler;
                            ((UIElement3D)o).FocusableChanged -= _focusableChangedEventHandler;
                        }
                    }
                    if (_focus != null)
                    {
                        o = _focus;
                        if (InputElement.IsUIElement(o))
                        {
                            ((UIElement)o).IsEnabledChanged += _isEnabledChangedEventHandler;
                            ((UIElement)o).IsVisibleChanged += _isVisibleChangedEventHandler;
                            ((UIElement)o).FocusableChanged += _focusableChangedEventHandler;
                        }
                        else if (InputElement.IsContentElement(o))
                        {
                            ((ContentElement)o).IsEnabledChanged += _isEnabledChangedEventHandler;
                            // NOTE: there is no IsVisible property for ContentElements.
                            ((ContentElement)o).FocusableChanged += _focusableChangedEventHandler;
                        }
                        else
                        {
                            ((UIElement3D)o).IsEnabledChanged += _isEnabledChangedEventHandler;
                            ((UIElement3D)o).IsVisibleChanged += _isVisibleChangedEventHandler;
                            ((UIElement3D)o).FocusableChanged += _focusableChangedEventHandler;
                        }
                    }
                }

                // Oddly enough, update the FocusWithinProperty properties first.  This is
                // so any callbacks will see the more-common FocusWithinProperty properties
                // set correctly.
                UIElement.FocusWithinProperty.OnOriginValueChanged(oldFocus, _focus, ref _focusTreeState);

                // Invalidate the IsKeyboardFocused properties.
                if (oldFocus != null)
                {
                    o = oldFocus;
                    o.SetValue(UIElement.IsKeyboardFocusedPropertyKey, false); // Same property for ContentElements
                }
                if (_focus != null)
                {
                    // Invalidate the IsKeyboardFocused property.
                    o = _focus;
                    o.SetValue(UIElement.IsKeyboardFocusedPropertyKey, true); // Same property for ContentElements
                }

                // Call TestServicesManager change the focus of the InputMethod is enable/disabled accordingly
                // so it's ready befere the GotKeyboardFocusEvent handler is invoked.
                if (_TsfManager != null)
                {
                    _TsfManager.Value.Focus(_focus);
                }

                // InputLanguageManager checks the preferred input languages.
                // This should before GotEvent because the preferred input language
                // should be set at the event handler.
                InputLanguageManager.Current.Focus(_focus, oldFocus);

                // Send the LostKeyboardFocus and GotKeyboardFocus events.
                if (oldFocus != null)
                {
                    KeyboardFocusChangedEventArgs lostFocus = new KeyboardFocusChangedEventArgs(this, timestamp, (IInputElement)oldFocus, (IInputElement)focus);
                    lostFocus.RoutedEvent = Keyboard.LostKeyboardFocusEvent;
                    lostFocus.Source      = oldFocus;
                    if (_inputManager != null)
                    {
                        _inputManager.Value.ProcessInput(lostFocus);
                    }
                }
                if (_focus != null)
                {
                    KeyboardFocusChangedEventArgs gotFocus = new KeyboardFocusChangedEventArgs(this, timestamp, (IInputElement)oldFocus, (IInputElement)_focus);
                    gotFocus.RoutedEvent = Keyboard.GotKeyboardFocusEvent;
                    gotFocus.Source      = _focus;
                    if (_inputManager != null)
                    {
                        _inputManager.Value.ProcessInput(gotFocus);
                    }
                }

                // InputMethod checks the preferred ime state.
                // The preferred input methods should be applied after Cicero TIP gots SetFocus callback.
                InputMethod.Current.GotKeyboardFocus(_focus);

                //Could be also built-in into IsKeyboardFocused_Changed static on UIElement and ContentElement
                //However the Automation likes to go immediately back on us so it would be better be last one...
                AutomationPeer.RaiseFocusChangedEventHelper((IInputElement)_focus);
            }
        }