예제 #1
0
        /// <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);
                    }
                }
            }
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        /// <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);
        }
예제 #6
0
        /// <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);
                    }
                }
            }
        }