public static void AddHandler(this UIElement that, SW.ExtendedRoutedEvent routedEvent, Delegate handler, bool handledEventsToo) { if (routedEvent == null) { throw new ArgumentNullException("routedEvent"); } if (handler == null) { throw new ArgumentNullException("handler"); } SW.DragEventHandler dragEventHandler = handler as SW.DragEventHandler; if (targetEvents.Contains(routedEvent) && dragEventHandler == null) { throw new InvalidOperationException(System.Windows.Controls.Properties.Resources.UIElementExtendedRoutedEventExtensions_TypeOfHandlerMustBeDragEventHandler); } if (routedEvent == SW.DragDrop.DragEnterEvent) { SW.DragDrop.AddDragEnterHandler(that, dragEventHandler, handledEventsToo); } else if (routedEvent == SW.DragDrop.DragOverEvent) { SW.DragDrop.AddDragOverHandler(that, dragEventHandler, handledEventsToo); } else if (routedEvent == SW.DragDrop.DragLeaveEvent) { SW.DragDrop.AddDragLeaveHandler(that, dragEventHandler, handledEventsToo); } else if (routedEvent == SW.DragDrop.DropEvent) { SW.DragDrop.AddDropHandler(that, dragEventHandler, handledEventsToo); } else if (routedEvent == SW.DragDrop.GiveFeedbackEvent) { SW.GiveFeedbackEventHandler giveFeedbackHandler = handler as SW.GiveFeedbackEventHandler; if (giveFeedbackHandler == null) { throw new InvalidOperationException(System.Windows.Controls.Properties.Resources.UIElementExtendedRoutedEventExtensions_TypeOfHandlerMustBeGiveFeedbackEventHandler); } SW.DragDrop.AddGiveFeedbackHandler(that, giveFeedbackHandler, handledEventsToo); } else if (routedEvent == SW.DragDrop.QueryContinueDragEvent) { SW.QueryContinueDragEventHandler queryContinueFeedbackHandler = handler as SW.QueryContinueDragEventHandler; if (queryContinueFeedbackHandler == null) { throw new InvalidOperationException(System.Windows.Controls.Properties.Resources.UIElementExtendedRoutedEventExtensions_TypeOfHandlerMustBeQueryContinueDragEventHandler); } SW.DragDrop.AddQueryContinueDragHandler(that, queryContinueFeedbackHandler, handledEventsToo); } }
/// <summary> /// Returns an observable that returns a SW.DragDropKeyStates value /// whenever it changes, even if one of the events involved /// is handled. /// </summary> /// <param name="that">The element to listen to.</param> /// <param name="initialState">The initial state SW.DragDropKeyStates. /// </param> /// <returns>An observable that returns a SW.DragDropKeyStates value /// whenever it changes, even if one of the events involved /// is handled.</returns> internal static IObservable<SW.DragDropKeyStates> GetKeyStateChangedAlways( this UIElement that, SW.DragDropKeyStates initialState) { return GetKeyStateChanged(that.GetMouseLeftButtonDownAlways(), that.GetMouseLeftButtonUpAlways(), that.GetKeyDownAlways(), that.GetKeyUpAlways(), initialState); }
/// <summary> /// Returns an observable that returns a SW.DragDropKeyStates value /// whenever it changes, even if one of the events involved /// is handled or occurs in a sibling. /// </summary> /// <param name="that">The element to listen to.</param> /// <param name="initialState">The initial state SW.DragDropKeyStates. /// </param> /// <returns>An observable that returns a SW.DragDropKeyStates value /// whenever it changes, even if one of the events involved /// is handled.</returns> internal static IObservable<SW.DragDropKeyStates> GetKeyStateChangedOnSelfAndSiblingsAlways(this UIElement that, SW.DragDropKeyStates initialState) { IEnumerable<UIElement> popupRoots = VisualTreeExtensions.GetVisualDescendants(that) .OfType<Popup>() .Select(popup => popup.Child) .Where(popupRoot => popupRoot != null); return GetKeyStateChanged( popupRoots .Select(popupRoot => popupRoot.GetMouseLeftButtonDownAlways()) .Aggregate(that.GetMouseLeftButtonDownAlways(), (left, right) => left.Merge(right)), popupRoots .Select(popupRoot => popupRoot.GetMouseLeftButtonUpAlways()) .Aggregate(that.GetMouseLeftButtonUpAlways(), (left, right) => left.Merge(right)), popupRoots .Select(popupRoot => popupRoot.GetKeyUpAlways()) .Aggregate(that.GetKeyUpAlways(), (left, right) => left.Merge(right)), popupRoots .Select(popupRoot => popupRoot.GetKeyDownAlways()) .Aggregate(that.GetKeyDownAlways(), (left, right) => left.Merge(right)), initialState); }
/// <summary> /// Returns an observable that returns a SW.DragDropKeyStates value. The /// observable is composed of mouse down and up observables and key down /// and up observables. /// </summary> /// <param name="mouseDownObservable">An event raised when a mouse /// button is depressed.</param> /// <param name="mouseUpObservable">An event raised when a mouse button /// is released.</param> /// <param name="keyDownObservable">An event raised when a key is /// pressed down.</param> /// <param name="keyUpObservable">An event raised when a key is /// released.</param> /// <param name="initialState">The initial state of the drag and /// drop keys.</param> /// <returns>An observable that returns a SW.DragDropKeyStates value /// whenever it changes, even if one of the events involved /// is handled.</returns> private static IObservable<SW.DragDropKeyStates> GetKeyStateChanged( IObservable<Event<MouseButtonEventArgs>> mouseDownObservable, IObservable<Event<MouseButtonEventArgs>> mouseUpObservable, IObservable<Event<KeyEventArgs>> keyDownObservable, IObservable<Event<KeyEventArgs>> keyUpObservable, SW.DragDropKeyStates initialState) { return mouseDownObservable .Select(ev => Tuple.Create(true, SW.DragDropKeyStates.LeftMouseButton)) .Merge( mouseUpObservable .Select(ev => Tuple.Create(false, SW.DragDropKeyStates.LeftMouseButton))) .Merge( keyUpObservable .Select(ev => Tuple.Create(false, ToDragDropKeyStates(ev.EventArgs.Key)))) .Merge( keyDownObservable .Select(ev => Tuple.Create(true, ToDragDropKeyStates(ev.EventArgs.Key)))) .Scan<Tuple<bool, SW.DragDropKeyStates>, SW.DragDropKeyStates>( initialState, (acc, current) => { if (current.Item1) { return acc | current.Item2; } else { return acc & ~current.Item2; } }); }