/// <summary> /// Retrieves the visible containers in a LongListSelector and adds them to <paramref name="items"/>. /// </summary> /// <param name="list">LongListSelector that contains the items.</param> /// <param name="itemsPanel">Direct parent of the items.</param> /// <param name="items">List to populate with the containers currently in the viewport</param> /// <param name="selectContent"> /// Specifies whether to return the container or its content. /// For headers, we can't apply projections on the container directly (or everything will go blank), /// so we will apply them on the content instead. /// </param> private static void AddVisibileContainers(LongListSelector list, Canvas itemsPanel, List <KeyValuePair <double, FrameworkElement> > items, bool selectContent) { foreach (DependencyObject obj in VisualTreeExtensions.GetVisualChildren(itemsPanel)) { ContentPresenter container = obj as ContentPresenter; if (container != null && (!selectContent || (VisualTreeHelper.GetChildrenCount(container) == 1 && VisualTreeHelper.GetChild(container, 0) is FrameworkElement))) { GeneralTransform itemTransform = null; try { itemTransform = container.TransformToVisual(list); } catch (ArgumentException) { // Ignore failures when not in the visual tree break; } Rect boundingBox = new Rect(itemTransform.Transform(new Point()), itemTransform.Transform(new Point(container.ActualWidth, container.ActualHeight))); if (boundingBox.Bottom > 0 && boundingBox.Top < list.ActualHeight) { items.Add( new KeyValuePair <double, FrameworkElement>( boundingBox.Top, selectContent ? (FrameworkElement)VisualTreeHelper.GetChild(container, 0) : container)); } } } }
/// <summary> /// Method that takes care of setting the two way bindings for all the attached properties /// from MapOverlay to the actual UI (not the intermediary presenter). /// </summary> /// <remarks> /// Even though the MapOverlay is supposed to be the target, it is the source due to issues with /// setting a two way binding where the source is an attached property /// </remarks> /// <param name="mapOverlay">MapOverlay that will be used in the two way binding</param> internal static void BindMapOverlayProperties(MapOverlay mapOverlay) { MapOverlayItem mapOverlayItem; DependencyObject targetObject; mapOverlayItem = (MapOverlayItem)mapOverlay.Content; targetObject = VisualTreeExtensions.GetVisualChildren(mapOverlayItem).FirstOrDefault(); if (targetObject == null) { throw new InvalidOperationException("Could not bind the properties because there was no UI"); } BindMapOverlayProperties(mapOverlay, targetObject); }
/// <summary> /// Clear the bindings created when the overlay was created by MapChild /// </summary> /// <param name="mapOverlay">MapOverlay that was created by MapChild</param> internal static void ClearMapOverlayBindings(MapOverlay mapOverlay) { MapOverlayItem mapOverlayItem; DependencyObject targetObject; mapOverlayItem = (MapOverlayItem)mapOverlay.Content; targetObject = VisualTreeExtensions.GetVisualChildren(mapOverlayItem).FirstOrDefault(); // In some cases, the MapOverlay was not presented in the UI. // Bindings are create when the MapOverlay is presented in the, so // if there is no visual, there is nothing to clear. if (targetObject != null) { ClearMapOverlayBindings(mapOverlay, targetObject); } }