private void RemoveCore(PointerCaptureTarget target, PointerCaptureKind kinds) { global::System.Diagnostics.Debug.Assert( kinds != PointerCaptureKind.None, "The capture kind must be set to release pointer captures."); if (this.Log().IsEnabled(LogLevel.Information)) { this.Log().Info($"{target.Element.GetDebugName()}: Releasing ({kinds}) capture of pointer {Pointer}"); } // If we remove an explicit capture, we update the _localExplicitCaptures of the target element if (kinds.HasFlag(PointerCaptureKind.Explicit) && target.Kind.HasFlag(PointerCaptureKind.Explicit)) { target.Element._localExplicitCaptures.Remove(Pointer); } target.Kind &= ~kinds; // The element is no longer listening for events, remove it. if (target.Kind == PointerCaptureKind.None) { _targets.Remove(target.Element); } IsImplicitOnly = _targets.None(t => t.Value.Kind.HasFlag(PointerCaptureKind.Explicit)); // Validate / update the state of this capture EnsureEffectiveCaptureState(); }
/// <summary> /// Removes a UIElement from the targets of this capture. /// DO NOT USE directly, use instead the Release method on the UIElement in order to properly raise the PointerCaptureLost event. /// </summary> public PointerCaptureKind RemoveTarget(UIElement element, PointerCaptureKind kinds, out PointerRoutedEventArgs lastDispatched) { if (_targets.TryGetValue(element, out var target)) { // Validate if any of the requested kinds is handled if ((target.Kind & kinds) == 0) { lastDispatched = default; return(PointerCaptureKind.None); } } else { lastDispatched = default; return(PointerCaptureKind.None); } var removed = target.Kind & kinds; lastDispatched = target.LastDispatched; RemoveCore(target, kinds); return(removed); }
public bool TryAddTarget(UIElement element, PointerCaptureKind kind, PointerRoutedEventArgs relatedArgs = null) { global::System.Diagnostics.Debug.Assert( kind == PointerCaptureKind.Explicit || kind == PointerCaptureKind.Implicit, "The initial capture kind must be Explicit **OR** Implicit."); if (this.Log().IsEnabled(LogLevel.Information)) { this.Log().Info($"{element}: Capturing ({kind}) pointer {Pointer}"); } if (_targets.TryGetValue(element, out var target)) { // Validate if the requested kind is not already handled if (target.Kind.HasFlag(kind)) { return(false); } else { // Add the new kind to the target target.Kind |= kind; } } else { target = new PointerCaptureTarget(element, kind); _targets.Add(element, target); // If the capture is made while raising an event (usually captures are made in PointerPressed handlers) // we re-use the current event args (if they match) to init the target.LastDispatched property. // Note: we don't check the sender as we may capture on another element but the frame ID is still correct. if (relatedArgs?.Pointer == Pointer) { Update(target, relatedArgs); // In case of an implicit capture we also override the native element used for the capture. // cf. remarks of the PointerCaptureTarget.NativeCaptureElement. if (kind == PointerCaptureKind.Implicit) { target.NativeCaptureElement = relatedArgs?.OriginalSource as UIElement ?? element; } } } // If we added an explicit capture, we update the _localExplicitCaptures of the target element if (kind == PointerCaptureKind.Explicit) { IsImplicitOnly = false; element._localExplicitCaptures.Add(Pointer); } // Make sure that this capture is effective EnsureEffectiveCaptureState(); return(true); }
public PointerCaptureTarget(UIElement element, PointerCaptureKind kind) { NativeCaptureElement = Element = element; Kind = kind; }
public IEnumerable <PointerCaptureTarget> GetTargets(PointerCaptureKind kinds) => _targets .Values .Where(target => (target.Kind & kinds) != PointerCaptureKind.None);
public bool IsTarget(UIElement element, PointerCaptureKind kinds) => _targets.TryGetValue(element, out var target) && (target.Kind & kinds) != PointerCaptureKind.None;