Exemplo n.º 1
0
 private static void OnAccessKeyPressed(object sender, AccessKeyPressedEventArgs e)
 {
     if (!e.Handled && e.Scope == null && e.Target == null)
     {
         e.Target = sender as GroupBox;
     }
 }
Exemplo n.º 2
0
            private void OnAccessKeyPressed(object sender, System.Windows.Input.AccessKeyPressedEventArgs e)
            {
                string rawKey = e.Key;

                if (Int32.TryParse(rawKey, out int index))
                {
                    rawKey = $"D{index}";
                }

                if (Enum.TryParse(rawKey, out Key pressed) && pressed != Key.None)
                {
                    AccessKeyPressingEventArgs args = new AccessKeyPressingEventArgs(keys, pressed);
                    if (pressingHandler != null)
                    {
                        pressingHandler(window, args);
                    }

                    if (!args.IsCancelled)
                    {
                        keys.Add(pressed);
                    }

                    e.Handled = true;
                }
            }
Exemplo n.º 3
0
 private void accessKeyPressed(object sender, System.Windows.Input.AccessKeyPressedEventArgs e)
 {
     if (Keyboard.Modifiers != ModifierKeys.Alt)
     {
         e.Scope   = sender;
         e.Handled = true;
     }
 }
 private static void HandleScopedElementAccessKeyPressed(object sender, AccessKeyPressedEventArgs e)
 {
     if (!Keyboard.IsKeyDown(Key.LeftAlt) && !Keyboard.IsKeyDown(Key.RightAlt) && GetIsAccessKeyScope((DependencyObject)sender))
     {
         e.Scope = sender;
         e.Handled = true;
     }
 }
        /// <summary>
        /// Fixes access key scoping bug within the WPF framework.
        /// </summary>
        /// <param name="sender">Potential target of the current access keys.</param>
        /// <param name="e">
        /// Info object for the current access keys and proxy to effect it's confirmation.
        /// </param>
        /// <remarks>
        /// The problem is that all access key presses are scoped to the active window,
        /// regardless of what properties, handlers, scope etc. you may have set. Targets
        /// are objects that have potential to be the target of the access keys in effect.
        ///
        /// If you happen to have a current object focused and you press the access keys
        /// of one of it's child's targets it will execute the child target. But, if you
        /// also have a ancestor target, the ancestor target will be executed instead.
        /// That goes against intuition and standard Windows behavior.
        /// The root of this logic (bug) is within the HwndSource.OnMnemonicCore method.
        /// If the scope is set to anything but the active window's HwndSource, the
        /// target will not be executed and the handler for the next target in the chain
        /// will be called.
        /// This handler gets called for every target within the scope, which because
        /// of the bug is always at the window level of the active window. If you set
        /// e.Handled to true, no further handlers in the chain will be executed. However
        /// because setting the scope to anything other than active window's HwndSource
        /// causes the target not to be acted on, we can use it to not act on the target
        /// while not canceling the chain either, thereby allowing us to skip to the next
        /// target's handler. Note that if a handler does act on the target it will
        /// inheritably break the chain because the menu will lose focus and the next
        /// handlers won't apply anymore; because a target has already been confirmed.
        /// We will use this knowledge to resolve the issue.
        /// We will set the scope to something other than the active window's HwndSource,
        /// if we find that the incorrect element is being targeted for the access keys
        /// (because the target is out of scope). This will cause the target to be
        /// skipped and the next target's handler will be called.
        /// If we detect the target is correct, we'll just leave everything alone so the
        /// target will be confirmed.
        ///
        /// NOTE: Do not call AccessKeyManager.IsKeyRegistered as it will cause a
        /// <see cref="T:System.StackOverflowException"/> to be thrown. The key is
        /// registered otherwise this handler wouldn't be called for it, therefore
        /// there is no need to call it.
        /// </remarks>
        private static void HandleAccessKeyPressed(object sender, AccessKeyPressedEventArgs e)
        {
            var focusedElement = Keyboard.FocusedElement as FrameworkElement;
            if (focusedElement == null)
                return; // No focused element.

            if (Equals(sender, focusedElement))
                return; // This is the correct target.

            // Look through descendants tree to see if this target is a descendant of
            // the focused element. We will stop looking at either the end of the tree
            // or if a object with multiple children is encountered that this target
            // isn't a descendant of.

            // If no valid target is found, we'll set the scope to the sender which
            // results in skipping to the next target handler in the chain
            // (due to the bug).

            DependencyObject obj = focusedElement;
            while (obj != null)
            {
                int childCount = VisualTreeHelper.GetChildrenCount(obj);
                for (int i = 0; i < childCount; i++)
                {
                    if (VisualTreeHelper.GetChild(obj, i) == sender)
                        return; // Found correct target; let it execute.
                }

                if (childCount > 1)
                {
                    // This target isn't a direct descendant and there are multiple
                    // direct descendants; skip this target.
                    e.Scope = sender;
                    return;
                }

                if (childCount == 1)
                {
                    // This target isn't a direct descendant, but we'll keep looking
                    // down the descendants chain to see if it's a descendant of the
                    // direct descendant.
                    obj = VisualTreeHelper.GetChild(obj, 0);
                }
                else
                {
                    // End of the line; skip this target.
                    e.Scope = sender;
                    return;
                }
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Returns scope for the given element.
        /// </summary>
        /// <param name="element"></param>
        /// <param name="key"></param>
        /// <returns>Scope for the given element, null means the context global scope</returns>
        private AccessKeyInformation GetInfoForElement(IInputElement element, string key)
        {
            AccessKeyInformation info = new AccessKeyInformation();

            if (element != null)
            {
                AccessKeyPressedEventArgs args = new AccessKeyPressedEventArgs(key);

                element.RaiseEvent(args);
                info.Scope  = args.Scope;
                info.target = args.Target;
                if (info.Scope == null)
                {
                    info.Scope = GetSourceForElement(element);
                }
            }
            else
            {
                info.Scope = CriticalGetActiveSource();
            }
            return(info);
        }
Exemplo n.º 7
0
        private string GetAccessKeyCharacter(DependencyObject d)
        {
            // See what the local value for AccessKeyElement is first and start with that.
            WeakReference cachedElementWeakRef = (WeakReference)d.GetValue(AccessKeyElementProperty);
            IInputElement accessKeyElement = (cachedElementWeakRef != null) ? (IInputElement)cachedElementWeakRef.Target : null;

            if (accessKeyElement != null)
            {
                // First figure out if the target of accessKeyElement is still "d", then go find
                // the "primary" character for the accessKeyElement.  

                AccessKeyPressedEventArgs accessKeyPressedEventArgs = new AccessKeyPressedEventArgs();
                accessKeyElement.RaiseEvent(accessKeyPressedEventArgs);
                if (accessKeyPressedEventArgs.Target == d)
                {
                    // Because there is no way to get at the access key element's character from the
                    // element (there is no interface or anything) we have to go through all registered 
                    // access keys and see if this access key element is still registered and what its
                    // "primary" character is.
                
                    foreach (DictionaryEntry entry in Current._keyToElements)
                    {
                        ArrayList elements = (ArrayList)entry.Value;
                        for (int i = 0; i < elements.Count; i++)
                        {
                            // If this element matches accessKeyElement, then return the current character
                            WeakReference currentElementWeakRef = (WeakReference)elements[i];

                            if (currentElementWeakRef.Target == accessKeyElement)
                            {
                                return (string)entry.Key;
                            }
                        }
                    }
                }
            }


            // There was no access key stored or it no longer matched.  Clear out the cache and figure it out again.
            d.ClearValue(AccessKeyElementProperty);

            foreach (DictionaryEntry entry in Current._keyToElements)
            {
                ArrayList elements = (ArrayList)entry.Value;
                for (int i = 0; i < elements.Count; i++)
                {
                    // Determine the target for this element.  Cache the weak reference for the element on the target.
                    WeakReference currentElementWeakRef = (WeakReference)elements[i];
                    IInputElement currentElement = (IInputElement)currentElementWeakRef.Target;

                    if (currentElement != null)
                    {
                        AccessKeyPressedEventArgs accessKeyPressedEventArgs = new AccessKeyPressedEventArgs();
                        currentElement.RaiseEvent(accessKeyPressedEventArgs);

                        // If the target was non-null, cache the access key element on the target.
                        // if the target matches "d", return the current character.
                        if (accessKeyPressedEventArgs.Target != null)
                        {
                            accessKeyPressedEventArgs.Target.SetValue(AccessKeyElementProperty, currentElementWeakRef);

                            if (accessKeyPressedEventArgs.Target == d)
                            {
                                return (string)entry.Key;
                            }
                        }
                    }
                }
            }


            return String.Empty;
        }
        /// <summary>
        /// This is overridden to pass hot keys on to the contained user control.
        /// </summary>
        /// <param name="m">The message to pre-process</param>
        /// <returns>True if the message was handled, false if not</returns>
        /// <remarks>When a WPF user control is hosted in a docked tool window, the hot keys no longer work.
        /// This works around the problem by manually seeing if the control makes use of the hot key, and if
        /// it does, processing it here.</remarks>
        protected override bool PreProcessMessage(ref System.Windows.Forms.Message m)
        {
            if(m.Msg == 0x0100 /* WM_KEYDOWN */)
            {
                System.Windows.Forms.Keys keyCode = (System.Windows.Forms.Keys)m.WParam &
                    System.Windows.Forms.Keys.KeyCode;

                if(keyCode == System.Windows.Forms.Keys.F1)
                {
                    ApplicationCommands.Help.Execute(null, (UserControl)base.Content);
                    return true;
                }
            }

            if(m.Msg == 0x0104 /*WM_SYSKEYDOWN*/)
            {
                if(Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))
                {
                    // Cache a copy of the scope on first use
                    if(scope == null && base.Content != null)
                    {
                        // Get the scope for handling hot keys.  The key used here doesn't matter.  We're just
                        // getting the scope to use.
                        AccessKeyPressedEventArgs e = new AccessKeyPressedEventArgs("X");

                        ((UserControl)base.Content).RaiseEvent(e);
                        scope = e.Scope;
                    }

                    string key = ((char)m.WParam).ToString();

                    // See if the hot key is registered for the control.  If so, handle it.  Ignore Alt+F4 though
                    // as it should close Visual Studio (it comes through as a lowercase "s").
                    if(scope != null && key != "s" && AccessKeyManager.IsKeyRegistered(scope, key))
                    {
                        AccessKeyManager.ProcessKey(scope, key, false);
                        return true;
                    }
                }
            }

            return base.PreProcessMessage(ref m);
        }
Exemplo n.º 9
0
        private string GetAccessKeyCharacter(DependencyObject d)
        {
            // See what the local value for AccessKeyElement is first and start with that.
            WeakReference cachedElementWeakRef = (WeakReference)d.GetValue(AccessKeyElementProperty);
            IInputElement accessKeyElement     = (cachedElementWeakRef != null) ? (IInputElement)cachedElementWeakRef.Target : null;

            if (accessKeyElement != null)
            {
                // First figure out if the target of accessKeyElement is still "d", then go find
                // the "primary" character for the accessKeyElement.

                AccessKeyPressedEventArgs accessKeyPressedEventArgs = new AccessKeyPressedEventArgs();
                accessKeyElement.RaiseEvent(accessKeyPressedEventArgs);
                if (accessKeyPressedEventArgs.Target == d)
                {
                    // Because there is no way to get at the access key element's character from the
                    // element (there is no interface or anything) we have to go through all registered
                    // access keys and see if this access key element is still registered and what its
                    // "primary" character is.

                    foreach (DictionaryEntry entry in Current._keyToElements)
                    {
                        ArrayList elements = (ArrayList)entry.Value;
                        for (int i = 0; i < elements.Count; i++)
                        {
                            // If this element matches accessKeyElement, then return the current character
                            WeakReference currentElementWeakRef = (WeakReference)elements[i];

                            if (currentElementWeakRef.Target == accessKeyElement)
                            {
                                return((string)entry.Key);
                            }
                        }
                    }
                }
            }


            // There was no access key stored or it no longer matched.  Clear out the cache and figure it out again.
            d.ClearValue(AccessKeyElementProperty);

            foreach (DictionaryEntry entry in Current._keyToElements)
            {
                ArrayList elements = (ArrayList)entry.Value;
                for (int i = 0; i < elements.Count; i++)
                {
                    // Determine the target for this element.  Cache the weak reference for the element on the target.
                    WeakReference currentElementWeakRef = (WeakReference)elements[i];
                    IInputElement currentElement        = (IInputElement)currentElementWeakRef.Target;

                    if (currentElement != null)
                    {
                        AccessKeyPressedEventArgs accessKeyPressedEventArgs = new AccessKeyPressedEventArgs();
                        currentElement.RaiseEvent(accessKeyPressedEventArgs);

                        // If the target was non-null, cache the access key element on the target.
                        // if the target matches "d", return the current character.
                        if (accessKeyPressedEventArgs.Target != null)
                        {
                            accessKeyPressedEventArgs.Target.SetValue(AccessKeyElementProperty, currentElementWeakRef);

                            if (accessKeyPressedEventArgs.Target == d)
                            {
                                return((string)entry.Key);
                            }
                        }
                    }
                }
            }


            return(String.Empty);
        }
Exemplo n.º 10
0
 private static void OnAccessKeyPressed(object sender, AccessKeyPressedEventArgs e)
 {
     if (!e.Handled && e.Scope == null && e.Target == null)
     {
         e.Target = (UIElement)sender;
     }
 }
Exemplo n.º 11
0
 //--------------------------------------------------------------
 private static void OnAccessKeyPressed(object sender, AccessKeyPressedEventArgs eventArgs)
 {
     // This code is borrowed from the WPF TabItem.
     if (!eventArgs.Handled && eventArgs.Scope == null)
     {
         var dockTabItem = (DockTabItem)sender;
         if (eventArgs.Target == null)
         {
             eventArgs.Target = dockTabItem;
         }
         else if (!dockTabItem.IsSelected)    // If DockTabItem is not active it is a scope for its content elements.
         {
             eventArgs.Scope = dockTabItem;
             eventArgs.Handled = true;
         }
     }
 }
        // custom event to work around .NET bug to prevent access key fireup without ALT key pressed
        private static void OnAccessKeyPressed(object sender, AccessKeyPressedEventArgs e)
        {
            // allowing default for enter and escape keys
            if (Keyboard.IsKeyDown(Key.Enter) || Keyboard.IsKeyDown(Key.Escape))
                return;

            if (!e.Handled && e.Scope == null && (e.Target == null || e.Target is Label))
            {
                // If Alt key is not pressed - handle the event
                if ((Keyboard.Modifiers & ModifierKeys.Alt) != ModifierKeys.Alt)
                {
                    e.Target = null;
                    e.Handled = true;
                }
            }
        }
Exemplo n.º 13
0
		void GridAccessKeyPressed(object sender, AccessKeyPressedEventArgs e)
		{
			throw new NotImplementedException();
		}
Exemplo n.º 14
0
        private void UpdateIsDefaulted(IInputElement focus)
        { 
            // If it's not a default button, or nothing is focused, or it's disabled then it's not defaulted. 
            if (!IsDefault || focus == null || !IsEnabled)
            { 
                SetValue(IsDefaultedPropertyKey, BooleanBoxes.FalseBox);
                return;
            }
 
            DependencyObject focusDO = focus as DependencyObject;
            object thisScope, focusScope; 
 
            // If the focused thing is not in this scope then IsDefaulted = false
            AccessKeyPressedEventArgs e; 

            object isDefaulted = BooleanBoxes.FalseBox;
            try
            { 
                // Step 1: Determine the AccessKey scope from currently focused element
                e = new AccessKeyPressedEventArgs(); 
                focus.RaiseEvent(e); 
                focusScope = e.Scope;
 
                // Step 2: Determine the AccessKey scope from this button
                e = new AccessKeyPressedEventArgs();
                this.RaiseEvent(e);
                thisScope = e.Scope; 

                // Step 3: Compare scopes 
                if (thisScope == focusScope && (focusDO == null || (bool)focusDO.GetValue(KeyboardNavigation.AcceptsReturnProperty) == false)) 
                {
                    isDefaulted = BooleanBoxes.TrueBox; 
                }
            }
            finally
            { 
                SetValue(IsDefaultedPropertyKey, isDefaulted);
            } 
 
        }
Exemplo n.º 15
0
 private static void OnAccessKeyPressed(object sender, AccessKeyPressedEventArgs e)
 {
     Label label = sender as Label;
     // ISSUE: if this is handled in Control then we need to check here as well
     if (!e.Handled && e.Scope == null && (e.Target == null || e.Target == label))
     {
         e.Target = label.Target;
     }
 }
Exemplo n.º 16
0
 private void OnAccessKeyPressed(object sender, AccessKeyPressedEventArgs args)
 {
     foreach (string accessKey in _renameAccessKeys)
     {
         if (string.Compare(accessKey, args.Key, StringComparison.OrdinalIgnoreCase) == 0)
         {
             args.Target = this;
             args.Handled = true;
             return;
         }
     }
 }
Exemplo n.º 17
0
        private static void OnAccessKeyPressed(object sender, AccessKeyPressedEventArgs e)
        {
            MenuItem menuItem = sender as MenuItem;
            bool isScope = false;

            if (e.Target == null)
            {
                // MenuItem access key should not work if something else beside MenuBase has capture
                if (Mouse.Captured == null || Mouse.Captured is MenuBase)
                {
                    e.Target = menuItem;

                    // special case is if we are the original source and our submenu is open,
                    // this is the case where the mouse moved over the header and focus is on
                    // the menu item but really you want to access key processing to be in your
                    // submenu.
                    // This assumes that no one will ever directly register a MenuItem with the AKM.
                    if (e.OriginalSource == menuItem && menuItem.IsSubmenuOpen)
                    {
                        isScope = true;
                    }
                }
                else
                {
                    e.Handled = true;
                }
            }
            else if (e.Scope == null)
            {
                // We want menu items to be a scope, but not for any AKs in its header.

                // If e.Target is already filled in, check if it's a MenuItem.
                // If it is and it's not us, we are its scope (i.e. we're the first MenuItem
                // above it in the chain).  If it's not a MenuItem, we have to take the long way.
                if (e.Target != menuItem && e.Target is MenuItem)
                {
                    isScope = true;
                }
                else
                {
                    // This case handles when you have some non-MenuItem in a menu that can be
                    // the target of access keys, like a Button.

                    // MenuItems are a scope for all access keys which are outside of themselves.
                    // e.Source is the logical element in which the event was raised.
                    // If we can walk from the source to ourselves, then we are not correct
                    // scope of this access key; some parent should be.

                    DependencyObject source = e.Source as DependencyObject;

                    while (source != null)
                    {
                        // If we walk up to this Menuitem, we are not the scope.
                        if (source == menuItem)
                        {
                            break;
                        }

                        UIElement uiElement = source as UIElement;

                        // If we walk up to an item which is one of our children, we are their scope.
                        if ((uiElement != null) && (ItemsControlFromItemContainer(uiElement) == menuItem))
                        {
                            isScope = true;
                            break;
                        }

                        source = GetFrameworkParent(source);
                    }
                }
            }

            if (isScope)
            {
                e.Scope = menuItem;
                e.Handled = true;
            }
        }
        /// <summary>
        /// This is overridden to pass hot keys on to the contained user control.
        /// </summary>
        /// <param name="m">The message to pre-process</param>
        /// <returns>True if the message was handled, false if not</returns>
        /// <remarks>When a WPF user control is hosted in a docked tool window, the hot keys no longer
        /// work.  This works around the problem by manually seeing if the control makes use of the
        /// hot key, and if it does, processing it here.</remarks>
        protected override bool PreProcessMessage(ref System.Windows.Forms.Message m)
        {
            if(m.Msg == 0x0100 /* WM_KEYDOWN */)
            {
                System.Windows.Forms.Keys keyCode = (System.Windows.Forms.Keys)m.WParam &
                    System.Windows.Forms.Keys.KeyCode;

                if(keyCode == System.Windows.Forms.Keys.F1)
                {
                    ApplicationCommands.Help.Execute(null, ucTopicPreviewer);
                    return true;
                }
            }

            if(m.Msg == 0x0104 /*WM_SYSKEYDOWN*/)
            {
                if(Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))
                {
                    // Cache a copy of the scope on first use
                    if(scope == null && base.Content != null)
                    {
                        // Get the scope for handling hot keys.  The key used here doesn't matter.
                        // We're just getting the scope to use.
                        AccessKeyPressedEventArgs e = new AccessKeyPressedEventArgs("X");

                        ucTopicPreviewer.RaiseEvent(e);
                        scope = e.Scope;
                    }

                    string key = ((char)m.WParam).ToString();

                    // See if the hot key is registered for the control.  If so, handle it.
                    if(scope != null && AccessKeyManager.IsKeyRegistered(scope, key))
                    {
                        AccessKeyManager.ProcessKey(scope, key, false);
                        return true;
                    }
                }
            }

            return base.PreProcessMessage(ref m);
        }
Exemplo n.º 19
0
        //-------------------------------------------------------------------
        //
        //  Private Methods
        //
        //-------------------------------------------------------------------

        #region Private Methods

        private static void OnAccessKeyPressed(object sender, AccessKeyPressedEventArgs e)
        {
            if (!e.Handled && e.Scope == null)
            {
                TabItem tabItem = sender as TabItem;

                if (e.Target == null)
                {
                    e.Target = tabItem;
                }
                else if (!tabItem.IsSelected) // If TabItem is not active it is a scope for its content elements
                {
                    e.Scope = tabItem;
                    e.Handled = true;
                }
            }
        }
Exemplo n.º 20
0
        //--------------------------------------------------------------
        private static void OnAccessKeyPressed(object sender, AccessKeyPressedEventArgs eventArgs)
        {
            if (eventArgs.Handled || eventArgs.Scope != null)
                return;

            var focusedElement = Keyboard.FocusedElement as FrameworkElement;
            if (focusedElement == null)
                return;

            // Do not accept access keys that originated outside of the DockTabPane.
            var dockTabPane = (DockTabPane)sender;
            if (!dockTabPane.IsVisualAncestorOf(focusedElement))
            {
                // Do not set eventArgs.Handled because this would break the chain.
                // --> Setting the scope skips the current target.
                eventArgs.Scope = dockTabPane;

                // See DigitalRune.Windows.AccessKeyScope for additional information!
            }
        }
Exemplo n.º 21
0
        //-------------------------------------------------------------------
        //
        //  Private Methods
        //
        //-------------------------------------------------------------------

        #region Private Methods

        private static void OnAccessKeyPressed(object sender, AccessKeyPressedEventArgs e)
        {
            // If ALT is down, then blend our scope into the one above. Maybe bad, but only if Menu is not top-level.
            if (!(Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt)))
            {
                e.Scope = sender;
                e.Handled = true;
            }
        }
Exemplo n.º 22
0
        private AccessKeyInformation GetInfoForElement(IInputElement element, string key)
        {
            AccessKeyInformation info = new AccessKeyInformation();
            if (element != null)
            {
                AccessKeyPressedEventArgs args = new AccessKeyPressedEventArgs(key);

                element.RaiseEvent(args);
                info.Scope = args.Scope;
                info.target = args.Target;
                if (info.Scope == null)
                {
                    info.Scope = GetSourceForElement(element);
                }
            }
            else
            {
                info.Scope = CriticalGetActiveSource();
            }
            return info;
        }
Exemplo n.º 23
0
 private static void OnAccessKeyPressed(object sender, AccessKeyPressedEventArgs e)
 {
     e.Scope = sender;
     e.Handled = true;
 }
Exemplo n.º 24
0
 private void Window_AccessKeyPressed(object sender, System.Windows.Input.AccessKeyPressedEventArgs e)
 {
 }