Ejemplo n.º 1
0
            /// <summary>
            /// Validate if the provided routed event args are relevant for the given element according to the active captures
            /// </summary>
            /// <param name="element">The target element for which the args are validated</param>
            /// <param name="args">The pending pointer event args that is under test</param>
            /// <param name="autoRelease">A flag that allows to automatically release any pending out-dated capture (for PointerDown only)</param>
            /// <returns>A boolean which indicates if the args are valid or not for the given element</returns>
            public bool ValidateAndUpdate(UIElement element, PointerRoutedEventArgs args, bool autoRelease)
            {
                if ((autoRelease && MostRecentDispatchedEventFrameId < args.FrameId) ||
                    _nativeCaptureElement.GetHitTestVisibility() == HitTestability.Collapsed)
                {
                    // If 'autoRelease' we want to release any previous capture that was not release properly no matter the reason.
                    // BUT we don't want to release a capture that was made by a child control (so MostRecentDispatchedEventFrameId should already be equals to current FrameId).
                    // We also do not allow a control that is not loaded to keep a capture (they should all have been release on unload).
                    // ** This is an IMPORTANT safety catch to prevent the application to become unresponsive **
                    Clear();

                    return(true);
                }
                else if (_targets.TryGetValue(element, out var target))
                {
                    Update(target, args);

                    return(true);
                }
                else if (IsImplicitOnly)
                {
                    // If the capture is implicit, we should not filter out events for children elements.

                    return(true);
                }
                else
                {
                    // We should dispatch the event only if the control which has captured the pointer has already dispatched the event
                    // (Which actually means that the current control is a parent of the control which has captured the pointer)
                    // Remarks: This is not enough to determine parent-child relationship when we dispatch multiple events base on the same native event,
                    //			(as they will all have the same FrameId), however in that case we dispatch events layer per layer
                    //			instead of bubbling a single event before raising the next one, so we are safe.
                    //			The only limitation would be when mixing native vs. managed bubbling, but this check only prevents
                    //			the leaf of the tree to raise the event, so we cannot mix bubbling mode in that case.
                    return(MostRecentDispatchedEventFrameId >= args.FrameId);
                }
            }