Example #1
0
        private static void FindCommandBinding(CommandBindingCollection commandBindings, object sender, RoutedEventArgs e, ICommand command, bool execute)
        {
            int index = 0;

            while (true)
            {
                CommandBinding commandBinding = commandBindings.FindMatch(command, ref index);
                if (HandleCommandBinding(sender, e, commandBinding, execute))
                {
                    break;
                }
            }
        }
Example #2
0
        private static void FindCommandBinding(CommandBindingCollection commandBindings, object sender, RoutedEventArgs e, ICommand command, bool execute)
        {
            int index = 0;

            while (true)
            {
                CommandBinding commandBinding = commandBindings.FindMatch(command, ref index);
                if ((commandBinding == null) ||
                    (execute && ExecuteCommandBinding(sender, (ExecutedRoutedEventArgs)e, commandBinding)) ||
                    (!execute && CanExecuteCommandBinding(sender, (CanExecuteRoutedEventArgs)e, commandBinding)))
                {
                    break;
                }
            }
        }
Example #3
0
        private static void FindCommandBinding(object sender, RoutedEventArgs e, ICommand command, bool execute)
        {
            // Check local command bindings
            CommandBindingCollection commandBindings = null;
            DependencyObject         senderAsDO      = sender as DependencyObject;

            if (InputElement.IsUIElement(senderAsDO))
            {
                commandBindings = ((UIElement)senderAsDO).CommandBindingsInternal;
            }
            else if (InputElement.IsContentElement(senderAsDO))
            {
                commandBindings = ((ContentElement)senderAsDO).CommandBindingsInternal;
            }
            else if (InputElement.IsUIElement3D(senderAsDO))
            {
                commandBindings = ((UIElement3D)senderAsDO).CommandBindingsInternal;
            }
            if (commandBindings != null)
            {
                FindCommandBinding(commandBindings, sender, e, command, execute);
            }

            // If no command binding is found, check class command bindings
            // First find the relevant command bindings, under the lock.
            // Most of the time there are no such bindings;  most of the rest of
            // the time there is only one.   Lazy-allocate with this in mind.
            Tuple <Type, CommandBinding>         tuple = null; // zero or one binding
            List <Tuple <Type, CommandBinding> > list  = null; // more than one

            lock (_classCommandBindings.SyncRoot)
            {
                // Check from the current type to all the base types
                Type classType = sender.GetType();
                while (classType != null)
                {
                    CommandBindingCollection classCommandBindings = _classCommandBindings[classType] as CommandBindingCollection;
                    if (classCommandBindings != null)
                    {
                        int index = 0;
                        while (true)
                        {
                            CommandBinding commandBinding = classCommandBindings.FindMatch(command, ref index);
                            if (commandBinding != null)
                            {
                                if (tuple == null)
                                {
                                    tuple = new Tuple <Type, CommandBinding>(classType, commandBinding);
                                }
                                else
                                {
                                    if (list == null)
                                    {
                                        list = new List <Tuple <Type, CommandBinding> >();
                                        list.Add(tuple);
                                    }
                                    list.Add(new Tuple <Type, CommandBinding>(classType, commandBinding));
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                    classType = classType.BaseType;
                }
            }

            // execute the bindings.  This can call into user code, so it must
            // be done outside the lock to avoid deadlock.
            if (list != null)
            {
                // more than one binding
                ExecutedRoutedEventArgs   exArgs    = execute ? (ExecutedRoutedEventArgs)e : null;
                CanExecuteRoutedEventArgs canExArgs = execute ? null : (CanExecuteRoutedEventArgs)e;
                for (int i = 0; i < list.Count; ++i)
                {
                    // invoke the binding
                    if ((execute && ExecuteCommandBinding(sender, exArgs, list[i].Item2)) ||
                        (!execute && CanExecuteCommandBinding(sender, canExArgs, list[i].Item2)))
                    {
                        // if it succeeds, advance past the remaining bindings for this type
                        Type classType = list[i].Item1;
                        while (++i < list.Count && list[i].Item1 == classType)
                        {
                            // no body needed
                        }
                        --i;    // back up, so that the outer for-loop advances to the right place
                    }
                }
            }
            else if (tuple != null)
            {
                // only one binding
                if (execute)
                {
                    ExecuteCommandBinding(sender, (ExecutedRoutedEventArgs)e, tuple.Item2);
                }
                else
                {
                    CanExecuteCommandBinding(sender, (CanExecuteRoutedEventArgs)e, tuple.Item2);
                }
            }
        }
Example #4
0
        /// <summary>
        ///     Scans input and command bindings for matching gestures and executes the appropriate command
        /// </summary>
        /// <remarks>
        ///     Scans for command to execute in the following order:
        ///     - input bindings associated with the targetElement instance
        ///     - input bindings associated with the targetElement class
        ///     - command bindings associated with the targetElement instance
        ///     - command bindings associated with the targetElement class
        /// </remarks>
        /// <param name="targetElement">UIElement/ContentElement to be scanned for input and command bindings</param>
        /// <param name="inputEventArgs">InputEventArgs to be matched against for gestures</param>
        internal static void TranslateInput(IInputElement targetElement, InputEventArgs inputEventArgs)
        {
            if ((targetElement == null) || (inputEventArgs == null))
            {
                return;
            }

            ICommand      command   = null;
            IInputElement target    = null;
            object        parameter = null;

            // Determine UIElement/ContentElement/Neither type
            DependencyObject targetElementAsDO = targetElement as DependencyObject;
            bool             isUIElement       = InputElement.IsUIElement(targetElementAsDO);
            bool             isContentElement  = !isUIElement && InputElement.IsContentElement(targetElementAsDO);
            bool             isUIElement3D     = !isUIElement && !isContentElement && InputElement.IsUIElement3D(targetElementAsDO);

            // Step 1: Check local input bindings
            InputBindingCollection localInputBindings = null;

            if (isUIElement)
            {
                localInputBindings = ((UIElement)targetElement).InputBindingsInternal;
            }
            else if (isContentElement)
            {
                localInputBindings = ((ContentElement)targetElement).InputBindingsInternal;
            }
            else if (isUIElement3D)
            {
                localInputBindings = ((UIElement3D)targetElement).InputBindingsInternal;
            }
            if (localInputBindings != null)
            {
                InputBinding inputBinding = localInputBindings.FindMatch(targetElement, inputEventArgs);
                if (inputBinding != null)
                {
                    command   = inputBinding.Command;
                    target    = inputBinding.CommandTarget;
                    parameter = inputBinding.CommandParameter;
                }
            }

            // Step 2: If no command, check class input bindings
            if (command == null)
            {
                lock (_classInputBindings.SyncRoot)
                {
                    Type classType = targetElement.GetType();
                    while (classType != null)
                    {
                        InputBindingCollection classInputBindings = _classInputBindings[classType] as InputBindingCollection;
                        if (classInputBindings != null)
                        {
                            InputBinding inputBinding = classInputBindings.FindMatch(targetElement, inputEventArgs);
                            if (inputBinding != null)
                            {
                                command   = inputBinding.Command;
                                target    = inputBinding.CommandTarget;
                                parameter = inputBinding.CommandParameter;
                                break;
                            }
                        }
                        classType = classType.BaseType;
                    }
                }
            }

            // Step 3: If no command, check local command bindings
            if (command == null)
            {
                // Check for the instance level ones Next
                CommandBindingCollection localCommandBindings = null;
                if (isUIElement)
                {
                    localCommandBindings = ((UIElement)targetElement).CommandBindingsInternal;
                }
                else if (isContentElement)
                {
                    localCommandBindings = ((ContentElement)targetElement).CommandBindingsInternal;
                }
                else if (isUIElement3D)
                {
                    localCommandBindings = ((UIElement3D)targetElement).CommandBindingsInternal;
                }
                if (localCommandBindings != null)
                {
                    command = localCommandBindings.FindMatch(targetElement, inputEventArgs);
                }
            }

            // Step 4: If no command, look at class command bindings
            if (command == null)
            {
                lock (_classCommandBindings.SyncRoot)
                {
                    Type classType = targetElement.GetType();
                    while (classType != null)
                    {
                        CommandBindingCollection classCommandBindings = _classCommandBindings[classType] as CommandBindingCollection;
                        if (classCommandBindings != null)
                        {
                            command = classCommandBindings.FindMatch(targetElement, inputEventArgs);
                            if (command != null)
                            {
                                break;
                            }
                        }
                        classType = classType.BaseType;
                    }
                }
            }

            // Step 5: If found a command, then execute it (unless it is
            // the special "NotACommand" command, which we simply ignore without
            // setting Handled=true, so that the input bubbles up to the parent)
            if (command != null && command != ApplicationCommands.NotACommand)
            {
                // We currently do not support declaring the element with focus as the target
                // element by setting target == null.  Instead, we interpret a null target to indicate
                // the element that we are routing the event through, e.g. the targetElement parameter.
                if (target == null)
                {
                    target = targetElement;
                }

                bool continueRouting = false;

                RoutedCommand routedCommand = command as RoutedCommand;
                if (routedCommand != null)
                {
                    if (routedCommand.CriticalCanExecute(parameter,
                                                         target,
                                                         inputEventArgs.UserInitiated /*trusted*/,
                                                         out continueRouting))
                    {
                        // If the command can be executed, we never continue to route the
                        // input event.
                        continueRouting = false;

                        ExecuteCommand(routedCommand, parameter, target, inputEventArgs);
                    }
                }
                else
                {
                    if (command.CanExecute(parameter))
                    {
                        command.Execute(parameter);
                    }
                }

                // If we mapped an input event to a command, we should always
                // handle the input event - regardless of whether the command
                // was executed or not.  Unless the CanExecute handler told us
                // to continue the route.
                inputEventArgs.Handled = !continueRouting;
            }
        }
Example #5
0
 private static void FindCommandBinding(CommandBindingCollection commandBindings, object sender, RoutedEventArgs e, ICommand command, bool execute)
 {
     int index = 0;
     while (true)
     {
         CommandBinding commandBinding = commandBindings.FindMatch(command, ref index);
         if ((commandBinding == null) ||
             (execute && ExecuteCommandBinding(sender, (ExecutedRoutedEventArgs)e, commandBinding)) ||
             (!execute && CanExecuteCommandBinding(sender, (CanExecuteRoutedEventArgs)e, commandBinding)))
         {
             break;
         }
     }
 }