/// <summary> /// Adds a handler for the SourceChanged event to the element. /// </summary> /// <param name="element">The element to add the handler too.</param> /// <param name="handler">The hander to add.</param> /// <remarks> /// Even though this is a routed event handler, there are special /// restrictions placed on this event. /// 1) You cannot use the UIElement or ContentElement AddHandler() method. /// 2) Class handlers are not allowed. /// 3) The handlers will receive the SourceChanged event even if it was handled. /// Callers must have UIPermission(UIPermissionWindow.AllWindows) to call this API. /// </remarks> public static void AddSourceChangedHandler(IInputElement element, SourceChangedEventHandler handler) { if (element == null) { throw new ArgumentNullException("element"); } // Either UIElement or ContentElement if (!InputElement.IsValid(element)) { throw new ArgumentException(SR.Get(SRID.Invalid_IInputElement), "element"); } DependencyObject o = (DependencyObject)element; // o.VerifyAccess(); // I would rather throw an exception here, but the CLR doesn't // so we won't either. if (handler != null) { FrugalObjectList <RoutedEventHandlerInfo> info; if (InputElement.IsUIElement(o)) { UIElement uie = o as UIElement; uie.AddHandler(SourceChangedEvent, handler); info = uie.EventHandlersStore[SourceChangedEvent]; if (1 == info.Count) { uie.VisualAncestorChanged += new Visual.AncestorChangedEventHandler(uie.OnVisualAncestorChanged); AddElementToWatchList(uie); } } else if (InputElement.IsUIElement3D(o)) { UIElement3D uie3D = o as UIElement3D; uie3D.AddHandler(SourceChangedEvent, handler); info = uie3D.EventHandlersStore[SourceChangedEvent]; if (1 == info.Count) { uie3D.VisualAncestorChanged += new Visual.AncestorChangedEventHandler(uie3D.OnVisualAncestorChanged); AddElementToWatchList(uie3D); } } else { ContentElement ce = o as ContentElement; ce.AddHandler(SourceChangedEvent, handler); info = ce.EventHandlersStore[SourceChangedEvent]; if (1 == info.Count) { AddElementToWatchList(ce); } } } }
public static DependencyObject GetInputElementParent(DependencyObject element, DeferredElementTreeState treeState) { DependencyObject parent = element; while (true) { parent = GetCoreParent(parent, treeState); if (parent == null || InputElement.IsValid(parent)) { break; } } return(parent); }
internal override Point GetPosition(IInputElement relativeTo) { VerifyAccess(); // Validate that relativeTo is either a UIElement or a ContentElement if (relativeTo != null && !InputElement.IsValid(relativeTo)) { throw new InvalidOperationException(); } PresentationSource relativePresentationSource = null; if (relativeTo != null) { DependencyObject dependencyObject = relativeTo as DependencyObject; DependencyObject containingVisual = InputElement.GetContainingVisual(dependencyObject); if (containingVisual != null) { relativePresentationSource = PresentationSource.CriticalFromVisual(containingVisual); } } else { if (_inputSource != null) { relativePresentationSource = _inputSource.Value; } } // Verify that we have a valid PresentationSource with a valid RootVisual // - if we don't we won't be able to invoke ClientToRoot or TranslatePoint and // we will just return 0,0 if (relativePresentationSource == null || relativePresentationSource.RootVisual == null) { return(new Point(0, 0)); } Point curPoint = new Point(_pointerData.Info.ptPixelLocationRaw.X, _pointerData.Info.ptPixelLocationRaw.Y); Point ptClient = PointUtil.ScreenToClient(curPoint, relativePresentationSource); Point ptRoot = PointUtil.ClientToRoot(ptClient, relativePresentationSource); Point ptRelative = InputElement.TranslatePoint(ptRoot, relativePresentationSource.RootVisual, (DependencyObject)relativeTo); return(ptRelative); }
internal IInputElement FindTarget(PresentationSource inputSource, Point position) { IInputElement stylusOver = null; switch (_captureMode) { case CaptureMode.None: { stylusOver = StylusDevice.GlobalHitTest(inputSource, position); // We understand UIElements and ContentElements. // If we are over something else (like a raw visual) // find the containing element. if (!InputElement.IsValid(stylusOver)) { stylusOver = InputElement.GetContainingInputElement(stylusOver as DependencyObject); } } break; case CaptureMode.Element: stylusOver = _stylusCapture; break; case CaptureMode.SubTree: { IInputElement stylusCapture = InputElement.GetContainingInputElement(_stylusCapture as DependencyObject); if (stylusCapture != null && inputSource != null) { // We need to re-hit-test to get the "real" UIElement we are over. // This allows us to have our capture-to-subtree span multiple windows. // GlobalHitTest always returns an IInputElement, so we are sure to have one. stylusOver = StylusDevice.GlobalHitTest(inputSource, position); } if (stylusOver != null && !InputElement.IsValid(stylusOver)) { stylusOver = InputElement.GetContainingInputElement(stylusOver as DependencyObject); } // Make sure that the element we hit is acutally underneath // our captured element. Because we did a global hit test, we // could have hit an element in a completely different window. // // Note that we support the child being in a completely different window. // So we use the GetUIParent method instead of just looking at // visual/content parents. if (stylusOver != null) { IInputElement ieTest = stylusOver; UIElement eTest = null; ContentElement ceTest = null; while (ieTest != null && ieTest != stylusCapture) { eTest = ieTest as UIElement; if (eTest != null) { ieTest = InputElement.GetContainingInputElement(eTest.GetUIParent(true)); } else { ceTest = ieTest as ContentElement; // Should never fail. ieTest = InputElement.GetContainingInputElement(ceTest.GetUIParent(true)); } } // If we missed the capture point, we didn't hit anything. if (ieTest != stylusCapture) { stylusOver = _stylusCapture; } } else { // We didn't hit anything. Consider the stylus over the capture point. stylusOver = _stylusCapture; } } break; } return(stylusOver); }
/// <summary> /// Captures the stylus to a particular element. /// </summary> internal override bool Capture(IInputElement element, CaptureMode captureMode) { int timeStamp = Environment.TickCount; VerifyAccess(); if (!(captureMode == CaptureMode.None || captureMode == CaptureMode.Element || captureMode == CaptureMode.SubTree)) { throw new System.ComponentModel.InvalidEnumArgumentException("captureMode", (int)captureMode, typeof(CaptureMode)); } if (element == null) { captureMode = CaptureMode.None; } if (captureMode == CaptureMode.None) { element = null; } // Validate that element is either a UIElement or a ContentElement DependencyObject doStylusCapture = element as DependencyObject; if (doStylusCapture != null && !InputElement.IsValid(element)) { throw new InvalidOperationException(SR.Get(SRID.Invalid_IInputElement, doStylusCapture.GetType())); } doStylusCapture?.VerifyAccess(); bool success = false; // The element we are capturing to must be both enabled and visible. UIElement e = element as UIElement; if ((e?.IsVisible ?? false) || (e?.IsEnabled ?? false)) { success = true; } else { ContentElement ce = element as ContentElement; if (ce?.IsEnabled ?? false) { success = true; } else { // Setting capture to null. success = true; } } if (success) { ChangeStylusCapture(element, captureMode, timeStamp); } return(success); }
/// <summary> /// Removes a handler for the SourceChanged event to the element. /// </summary> /// <param name="e">The element to remove the handler from.</param> /// <param name="handler">The hander to remove.</param> /// <remarks> /// Even though this is a routed event handler, there are special /// restrictions placed on this event. /// 1) You cannot use the UIElement or ContentElement RemoveHandler() method. /// </remarks> public static void RemoveSourceChangedHandler(IInputElement e, SourceChangedEventHandler handler) { if (e == null) { throw new ArgumentNullException("e"); } if (!InputElement.IsValid(e)) { throw new ArgumentException(SR.Get(SRID.Invalid_IInputElement), "e"); } DependencyObject o = (DependencyObject)e; // o.VerifyAccess(); // I would rather throw an exception here, but the CLR doesn't // so we won't either. if (handler != null) { FrugalObjectList <RoutedEventHandlerInfo> info = null; EventHandlersStore store; // Either UIElement or ContentElement. if (InputElement.IsUIElement(o)) { UIElement uie = o as UIElement; uie.RemoveHandler(SourceChangedEvent, handler); store = uie.EventHandlersStore; if (store != null) { info = store[SourceChangedEvent]; } if (info == null || info.Count == 0) { uie.VisualAncestorChanged -= new Visual.AncestorChangedEventHandler(uie.OnVisualAncestorChanged);; RemoveElementFromWatchList(uie); } } else if (InputElement.IsUIElement3D(o)) { UIElement3D uie3D = o as UIElement3D; uie3D.RemoveHandler(SourceChangedEvent, handler); store = uie3D.EventHandlersStore; if (store != null) { info = store[SourceChangedEvent]; } if (info == null || info.Count == 0) { uie3D.VisualAncestorChanged -= new Visual.AncestorChangedEventHandler(uie3D.OnVisualAncestorChanged);; RemoveElementFromWatchList(uie3D); } } else { ContentElement ce = o as ContentElement; ce.RemoveHandler(SourceChangedEvent, handler); store = ce.EventHandlersStore; if (store != null) { info = store[SourceChangedEvent]; } if (info == null || info.Count == 0) { RemoveElementFromWatchList(ce); } } } }