diff --git a/MapControl/Shared/MapItemsControl.cs b/MapControl/Shared/MapItemsControl.cs index 6903aef3..0644fd54 100644 --- a/MapControl/Shared/MapItemsControl.cs +++ b/MapControl/Shared/MapItemsControl.cs @@ -33,12 +33,27 @@ namespace MapControl MapPanel.InitMapElement(this); } + /// + /// Wrapper for the MapPanel.AutoCollapse attached property. + /// + public bool AutoCollapse + { + get { return (bool)GetValue(AutoCollapseProperty); } + set { SetValue(AutoCollapseProperty, value); } + } + + /// + /// Wrapper for the MapPanel.Location attached property. + /// public Location Location { get { return (Location)GetValue(LocationProperty); } set { SetValue(LocationProperty, value); } } + /// + /// Path to a source property for binding the Location property. + /// public string LocationMemberPath { get { return (string)GetValue(LocationMemberPathProperty); } diff --git a/MapControl/Shared/MapPanel.cs b/MapControl/Shared/MapPanel.cs index cfd5493a..eb8dc54a 100644 --- a/MapControl/Shared/MapPanel.cs +++ b/MapControl/Shared/MapPanel.cs @@ -31,13 +31,8 @@ namespace MapControl /// public partial class MapPanel : Panel, IMapElement { - private static void ParentMapPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) - { - if (obj is IMapElement mapElement) - { - mapElement.ParentMap = e.NewValue as MapBase; - } - } + public static readonly DependencyProperty AutoCollapseProperty = DependencyProperty.RegisterAttached( + "AutoCollapse", typeof(bool), typeof(MapPanel), new PropertyMetadata(false)); private MapBase parentMap; @@ -52,26 +47,58 @@ namespace MapControl InitMapElement(this); } + /// + /// Gets a value that controls whether an element's Visibility is automatically + /// set to Collapsed when it is located outside the visible viewport area. + /// + public static bool GetAutoCollapse(FrameworkElement element) + { + return (bool)element.GetValue(AutoCollapseProperty); + } + + /// + /// Sets the AutoCollapse property. + /// + public static void SetAutoCollapse(FrameworkElement element, bool value) + { + element.SetValue(AutoCollapseProperty, value); + } + + /// + /// Gets the geodetic Location of an element. + /// public static Location GetLocation(FrameworkElement element) { return (Location)element.GetValue(LocationProperty); } + /// + /// Sets the geodetic Location of an element. + /// public static void SetLocation(FrameworkElement element, Location value) { element.SetValue(LocationProperty, value); } + /// + /// Gets the BoundingBox of an element. + /// public static BoundingBox GetBoundingBox(FrameworkElement element) { return (BoundingBox)element.GetValue(BoundingBoxProperty); } + /// + /// Sets the BoundingBox of an element. + /// public static void SetBoundingBox(FrameworkElement element, BoundingBox value) { element.SetValue(BoundingBoxProperty, value); } + /// + /// Gets the position of an element in view coordinates. + /// public static Point? GetViewPosition(FrameworkElement element) { return (Point?)element.GetValue(ViewPositionProperty); @@ -80,8 +107,13 @@ namespace MapControl /// /// Returns the view position of a Location. /// - public Point GetViewPosition(Location location) + public Point? GetViewPosition(Location location) { + if (location == null) + { + return null; + } + var pos = parentMap.LocationToView(location); if (parentMap.MapProjection.IsNormalCylindrical && @@ -175,19 +207,32 @@ namespace MapControl { foreach (var element in Children.OfType()) { - var location = GetLocation(element); + var position = GetViewPosition(GetLocation(element)); - if (location != null) + SetViewPosition(element, position); + + if (GetAutoCollapse(element)) { - var position = GetViewPosition(location); + if (position.HasValue && + (position.Value.X < 0d || + position.Value.Y < 0d || + position.Value.X > parentMap.RenderSize.Width || + position.Value.Y > parentMap.RenderSize.Height)) + { + element.SetValue(VisibilityProperty, Visibility.Collapsed); + } + else + { + element.ClearValue(VisibilityProperty); + } + } - SetViewPosition(element, position); - ArrangeElement(element, position); + if (position.HasValue) + { + ArrangeElement(element, position.Value); } else { - SetViewPosition(element, null); - var boundingBox = GetBoundingBox(element); if (boundingBox != null) @@ -314,5 +359,13 @@ namespace MapControl element.Arrange(rect); } + + private static void ParentMapPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) + { + if (obj is IMapElement mapElement) + { + mapElement.ParentMap = e.NewValue as MapBase; + } + } } } diff --git a/MapControl/Shared/MapPath.cs b/MapControl/Shared/MapPath.cs index d98a8744..f0b19871 100644 --- a/MapControl/Shared/MapPath.cs +++ b/MapControl/Shared/MapPath.cs @@ -29,6 +29,15 @@ namespace MapControl MapPanel.InitMapElement(this); } + /// + /// Wrapper for the MapPanel.AutoCollapse attached property. + /// + public bool AutoCollapse + { + get { return (bool)GetValue(AutoCollapseProperty); } + set { SetValue(AutoCollapseProperty, value); } + } + /// /// Gets or sets a Location that is used as /// - either the origin point of a geometry specified in cartesian map units (meters) diff --git a/MapControl/Shared/Pushpin.cs b/MapControl/Shared/Pushpin.cs index a46d8401..b764333c 100644 --- a/MapControl/Shared/Pushpin.cs +++ b/MapControl/Shared/Pushpin.cs @@ -17,13 +17,18 @@ namespace MapControl /// public class Pushpin : ContentControl { - public static readonly DependencyProperty LocationProperty = #if WINDOWS_UWP - DependencyProperty.Register( - nameof(Location), typeof(Location), typeof(Pushpin), - new PropertyMetadata(null, (o, e) => MapPanel.SetLocation((FrameworkElement)o, (Location)e.NewValue))); + public static readonly DependencyProperty AutoCollapseProperty = DependencyProperty.Register( + nameof(AutoCollapse), typeof(bool), typeof(Pushpin), + new PropertyMetadata(false, (o, e) => MapPanel.SetAutoCollapse((FrameworkElement)o, (bool)e.NewValue))); + + public static readonly DependencyProperty LocationProperty = DependencyProperty.Register( + nameof(Location), typeof(Location), typeof(Pushpin), + new PropertyMetadata(null, (o, e) => MapPanel.SetLocation((FrameworkElement)o, (Location)e.NewValue))); #else - MapPanel.LocationProperty.AddOwner(typeof(Pushpin)); + public static readonly DependencyProperty AutoCollapseProperty = MapPanel.AutoCollapseProperty.AddOwner(typeof(Pushpin)); + + public static readonly DependencyProperty LocationProperty = MapPanel.LocationProperty.AddOwner(typeof(Pushpin)); #endif public Pushpin() { @@ -32,6 +37,18 @@ namespace MapControl MapPanel.InitMapElement(this); } + /// + /// Wrapper for the MapPanel.AutoCollapse attached property. + /// + public bool AutoCollapse + { + get { return (bool)GetValue(AutoCollapseProperty); } + set { SetValue(AutoCollapseProperty, value); } + } + + /// + /// Wrapper for the MapPanel.Location attached property. + /// public Location Location { get { return (Location)GetValue(LocationProperty); } diff --git a/MapControl/UWP/MapItemsControl.UWP.cs b/MapControl/UWP/MapItemsControl.UWP.cs index 941c7e99..4c843524 100644 --- a/MapControl/UWP/MapItemsControl.UWP.cs +++ b/MapControl/UWP/MapItemsControl.UWP.cs @@ -11,6 +11,10 @@ namespace MapControl { public partial class MapItem { + public static readonly DependencyProperty AutoCollapseProperty = DependencyProperty.Register( + nameof(AutoCollapse), typeof(bool), typeof(MapItem), + new PropertyMetadata(false, (o, e) => MapPanel.SetAutoCollapse((FrameworkElement)o, (bool)e.NewValue))); + public static readonly DependencyProperty LocationProperty = DependencyProperty.Register( nameof(Location), typeof(Location), typeof(MapItem), new PropertyMetadata(null, (o, e) => MapPanel.SetLocation((FrameworkElement)o, (Location)e.NewValue))); diff --git a/MapControl/UWP/MapPath.UWP.cs b/MapControl/UWP/MapPath.UWP.cs index 2822eba7..80de4a76 100644 --- a/MapControl/UWP/MapPath.UWP.cs +++ b/MapControl/UWP/MapPath.UWP.cs @@ -14,6 +14,10 @@ namespace MapControl { public partial class MapPath : Path { + public static readonly DependencyProperty AutoCollapseProperty = DependencyProperty.Register( + nameof(AutoCollapse), typeof(bool), typeof(MapPath), + new PropertyMetadata(false, (o, e) => MapPanel.SetAutoCollapse((FrameworkElement)o, (bool)e.NewValue))); + #region Methods used only by derived classes MapPolyline and MapPolygon protected void DataCollectionPropertyChanged(DependencyPropertyChangedEventArgs e) diff --git a/MapControl/WPF/MapItemsControl.WPF.cs b/MapControl/WPF/MapItemsControl.WPF.cs index 950bb891..2ff5c2da 100644 --- a/MapControl/WPF/MapItemsControl.WPF.cs +++ b/MapControl/WPF/MapItemsControl.WPF.cs @@ -11,6 +11,8 @@ namespace MapControl { public partial class MapItem { + public static readonly DependencyProperty AutoCollapseProperty = MapPanel.AutoCollapseProperty.AddOwner(typeof(MapItem)); + public static readonly DependencyProperty LocationProperty = MapPanel.LocationProperty.AddOwner(typeof(MapItem)); protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) diff --git a/MapControl/WPF/MapPath.WPF.cs b/MapControl/WPF/MapPath.WPF.cs index 7e79ad85..bed810a7 100644 --- a/MapControl/WPF/MapPath.WPF.cs +++ b/MapControl/WPF/MapPath.WPF.cs @@ -14,6 +14,8 @@ namespace MapControl { public partial class MapPath : Shape, IWeakEventListener { + public static readonly DependencyProperty AutoCollapseProperty = MapPanel.AutoCollapseProperty.AddOwner(typeof(MapPath)); + public static readonly DependencyProperty DataProperty = Path.DataProperty.AddOwner(typeof(MapPath)); public Geometry Data diff --git a/SampleApps/UniversalApp/MainPage.xaml b/SampleApps/UniversalApp/MainPage.xaml index 3156bd2a..a298f9d5 100644 --- a/SampleApps/UniversalApp/MainPage.xaml +++ b/SampleApps/UniversalApp/MainPage.xaml @@ -21,6 +21,7 @@