Version 2.12.0: Added a MapPath.Location property for adjusting the viewport position to the visible viewport area. The property replaces the behavior that was previously achieved by setting the MapPanel.Location attached properties on a MapPath. In addition, MapItem and Pushpin now also have a Location property that behaves like MapPanel.Location.

This commit is contained in:
ClemensF 2016-08-08 20:36:02 +02:00
parent da684bff95
commit 4d2d6c1273
30 changed files with 234 additions and 195 deletions

View file

@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("© 2016 Clemens Fischer")] [assembly: AssemblyCopyright("© 2016 Clemens Fischer")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("2.11.0")] [assembly: AssemblyVersion("2.12.0")]
[assembly: AssemblyFileVersion("2.11.0")] [assembly: AssemblyFileVersion("2.12.0")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View file

@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("© 2016 Clemens Fischer")] [assembly: AssemblyCopyright("© 2016 Clemens Fischer")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("2.11.0")] [assembly: AssemblyVersion("2.12.0")]
[assembly: AssemblyFileVersion("2.11.0")] [assembly: AssemblyFileVersion("2.12.0")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View file

@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("© 2016 Clemens Fischer")] [assembly: AssemblyCopyright("© 2016 Clemens Fischer")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("2.11.0")] [assembly: AssemblyVersion("2.12.0")]
[assembly: AssemblyFileVersion("2.11.0")] [assembly: AssemblyFileVersion("2.12.0")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View file

@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("© 2016 Clemens Fischer")] [assembly: AssemblyCopyright("© 2016 Clemens Fischer")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("2.11.0")] [assembly: AssemblyVersion("2.12.0")]
[assembly: AssemblyFileVersion("2.11.0")] [assembly: AssemblyFileVersion("2.12.0")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View file

@ -8,9 +8,4 @@ namespace MapControl
{ {
MapBase ParentMap { get; set; } MapBase ParentMap { get; set; }
} }
public interface IMapShape : IMapElement
{
void LocationChanged(Location oldValue, Location newValue);
}
} }

View file

@ -2,6 +2,8 @@
// © 2016 Clemens Fischer // © 2016 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL) // Licensed under the Microsoft Public License (Ms-PL)
using System;
using Windows.Foundation;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Input; using Windows.UI.Xaml.Input;
@ -15,6 +17,11 @@ namespace MapControl
public static readonly DependencyProperty MouseWheelZoomDeltaProperty = DependencyProperty.Register( public static readonly DependencyProperty MouseWheelZoomDeltaProperty = DependencyProperty.Register(
"MouseWheelZoomDelta", typeof(double), typeof(Map), new PropertyMetadata(1d)); "MouseWheelZoomDelta", typeof(double), typeof(Map), new PropertyMetadata(1d));
private bool transformPending;
private Point transformTranslation;
private double transformRotation;
private double transformScale = 1d;
public Map() public Map()
{ {
ManipulationMode = ManipulationModes.Scale | ManipulationMode = ManipulationModes.Scale |
@ -33,16 +40,36 @@ namespace MapControl
set { SetValue(MouseWheelZoomDeltaProperty, value); } set { SetValue(MouseWheelZoomDeltaProperty, value); }
} }
private void OnPointerWheelChanged(object sender, PointerRoutedEventArgs e) protected virtual void OnPointerWheelChanged(object sender, PointerRoutedEventArgs e)
{ {
var point = e.GetCurrentPoint(this); var point = e.GetCurrentPoint(this);
var zoomChange = MouseWheelZoomDelta * (double)point.Properties.MouseWheelDelta / 120d; var zoomChange = MouseWheelZoomDelta * point.Properties.MouseWheelDelta / 120d;
ZoomMap(point.Position, TargetZoomLevel + zoomChange); ZoomMap(point.Position, TargetZoomLevel + zoomChange);
} }
private void OnManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e) protected virtual async void OnManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{ {
TransformMap(e.Position, e.Delta.Translation, e.Delta.Rotation, e.Delta.Scale); transformTranslation.X += e.Delta.Translation.X;
transformTranslation.Y += e.Delta.Translation.Y;
transformRotation += e.Delta.Rotation;
transformScale *= e.Delta.Scale;
if (!transformPending)
{
transformPending = true;
await Dispatcher.RunIdleAsync(a =>
{
TransformMap(e.Position, transformTranslation, transformRotation, transformScale);
transformPending = false;
transformTranslation.X = 0d;
transformTranslation.Y = 0d;
transformRotation = 0d;
transformScale = 1d;
});
}
} }
} }
} }

View file

@ -3,15 +3,14 @@
// Licensed under the Microsoft Public License (Ms-PL) // Licensed under the Microsoft Public License (Ms-PL)
using System; using System;
using System.Linq;
#if NETFX_CORE #if NETFX_CORE
using Windows.Foundation; using Windows.Foundation;
using Windows.UI; using Windows.UI;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Media;
#else #else
using System.Windows; using System.Windows;
using System.Windows.Controls;
using System.Windows.Media; using System.Windows.Media;
#endif #endif
@ -51,7 +50,7 @@ namespace MapControl
{ {
// set Background by Style to enable resetting by ClearValue in RemoveTileLayers // set Background by Style to enable resetting by ClearValue in RemoveTileLayers
var style = new Style(typeof(MapBase)); var style = new Style(typeof(MapBase));
style.Setters.Add(new Setter(Panel.BackgroundProperty, new SolidColorBrush(Colors.Transparent))); style.Setters.Add(new Setter(BackgroundProperty, new SolidColorBrush(Colors.Transparent)));
Style = style; Style = style;
var clip = new RectangleGeometry(); var clip = new RectangleGeometry();
@ -59,9 +58,13 @@ namespace MapControl
SizeChanged += (s, e) => SizeChanged += (s, e) =>
{ {
clip.Rect = new Rect(new Point(), e.NewSize); if (clip.Rect.Width != e.NewSize.Width || clip.Rect.Height != e.NewSize.Height)
{
clip.Rect = new Rect(0d, 0d, e.NewSize.Width, e.NewSize.Height);
ResetTransformOrigin(); ResetTransformOrigin();
UpdateTransform(); UpdateTransform();
}
}; };
} }

View file

@ -3,7 +3,6 @@
// Licensed under the Microsoft Public License (Ms-PL) // Licensed under the Microsoft Public License (Ms-PL)
using System; using System;
using System.Linq;
#if NETFX_CORE #if NETFX_CORE
using Windows.Foundation; using Windows.Foundation;
using Windows.UI.Xaml; using Windows.UI.Xaml;
@ -23,7 +22,7 @@ namespace MapControl
{ {
public partial class MapGraticule public partial class MapGraticule
{ {
private readonly Path path; private Path path;
private Location graticuleStart; private Location graticuleStart;
private Location graticuleEnd; private Location graticuleEnd;
@ -31,19 +30,28 @@ namespace MapControl
{ {
IsHitTestVisible = false; IsHitTestVisible = false;
StrokeThickness = 0.5; StrokeThickness = 0.5;
}
protected override void OnViewportChanged()
{
if (path == null)
{
path = new Path path = new Path
{ {
Data = new PathGeometry() Data = new PathGeometry()
}; };
path.SetBinding(Shape.StrokeProperty, new Binding path.SetBinding(Shape.StrokeProperty,
GetBindingExpression(StrokeProperty)?.ParentBinding ??
new Binding
{ {
Source = this, Source = this,
Path = new PropertyPath("Stroke") Path = new PropertyPath("Stroke")
}); });
path.SetBinding(Shape.StrokeThicknessProperty, new Binding path.SetBinding(Shape.StrokeThicknessProperty,
GetBindingExpression(StrokeThicknessProperty)?.ParentBinding ??
new Binding
{ {
Source = this, Source = this,
Path = new PropertyPath("StrokeThickness") Path = new PropertyPath("StrokeThickness")
@ -52,8 +60,6 @@ namespace MapControl
Children.Add(path); Children.Add(path);
} }
protected override void OnViewportChanged()
{
var bounds = ParentMap.ViewportTransform.Inverse.TransformBounds(new Rect(new Point(), ParentMap.RenderSize)); var bounds = ParentMap.ViewportTransform.Inverse.TransformBounds(new Rect(new Point(), ParentMap.RenderSize));
var start = ParentMap.MapTransform.Transform(new Point(bounds.X, bounds.Y)); var start = ParentMap.MapTransform.Transform(new Point(bounds.X, bounds.Y));
var end = ParentMap.MapTransform.Transform(new Point(bounds.X + bounds.Width, bounds.Y + bounds.Height)); var end = ParentMap.MapTransform.Transform(new Point(bounds.X + bounds.Width, bounds.Y + bounds.Height));
@ -143,7 +149,9 @@ namespace MapControl
RenderTransform = renderTransform RenderTransform = renderTransform
}; };
label.SetBinding(TextBlock.ForegroundProperty, new Binding label.SetBinding(TextBlock.ForegroundProperty,
GetBindingExpression(ForegroundProperty)?.ParentBinding ??
new Binding
{ {
Source = this, Source = this,
Path = new PropertyPath("Foreground") Path = new PropertyPath("Foreground")

View file

@ -20,5 +20,11 @@ namespace MapControl
DefaultStyleKey = typeof(MapItem); DefaultStyleKey = typeof(MapItem);
MapPanel.AddParentMapHandlers(this); MapPanel.AddParentMapHandlers(this);
} }
public Location Location
{
get { return (Location)GetValue(MapPanel.LocationProperty); }
set { SetValue(MapPanel.LocationProperty, value); }
}
} }
} }

View file

@ -17,5 +17,14 @@ namespace MapControl
DefaultStyleKeyProperty.OverrideMetadata( DefaultStyleKeyProperty.OverrideMetadata(
typeof(MapItem), new FrameworkPropertyMetadata(typeof(MapItem))); typeof(MapItem), new FrameworkPropertyMetadata(typeof(MapItem)));
} }
public static readonly DependencyProperty LocationProperty =
MapPanel.LocationProperty.AddOwner(typeof(MapItem));
public Location Location
{
get { return (Location)GetValue(LocationProperty); }
set { SetValue(LocationProperty, value); }
}
} }
} }

View file

@ -2,25 +2,24 @@
// © 2016 Clemens Fischer // © 2016 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL) // Licensed under the Microsoft Public License (Ms-PL)
#if !NETFX_CORE #if NETFX_CORE
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
#else
using Windows.UI.Text; using Windows.UI.Text;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Data; using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Media;
#else
namespace MapControl using System.Windows;
{ using System.Windows.Data;
class FontStyles { public const FontStyle Normal = FontStyle.Normal; } using System.Windows.Media;
class FontStretches { public const FontStretch Normal = FontStretch.Normal; }
}
#endif #endif
namespace MapControl namespace MapControl
{ {
#if NETFX_CORE
class FontStyles { public const FontStyle Normal = FontStyle.Normal; }
class FontStretches { public const FontStretch Normal = FontStretch.Normal; }
#endif
public partial class MapOverlay public partial class MapOverlay
{ {
public static readonly DependencyProperty FontSizeProperty = DependencyProperty.Register( public static readonly DependencyProperty FontSizeProperty = DependencyProperty.Register(
@ -68,20 +67,15 @@ namespace MapControl
public static readonly DependencyProperty StrokeMiterLimitProperty = DependencyProperty.Register( public static readonly DependencyProperty StrokeMiterLimitProperty = DependencyProperty.Register(
"StrokeMiterLimit", typeof(double), typeof(MapOverlay), new PropertyMetadata(1d)); "StrokeMiterLimit", typeof(double), typeof(MapOverlay), new PropertyMetadata(1d));
private Binding foregroundBinding;
private Binding strokeBinding;
protected override void SetParentMapOverride(MapBase parentMap) protected override void SetParentMapOverride(MapBase parentMap)
{ {
if (foregroundBinding != null) if (GetBindingExpression(ForegroundProperty) != null)
{ {
foregroundBinding = null;
ClearValue(ForegroundProperty); ClearValue(ForegroundProperty);
} }
if (strokeBinding != null) if (GetBindingExpression(StrokeProperty) != null)
{ {
strokeBinding = null;
ClearValue(StrokeProperty); ClearValue(StrokeProperty);
} }
@ -89,22 +83,20 @@ namespace MapControl
{ {
if (Foreground == null) if (Foreground == null)
{ {
foregroundBinding = new Binding SetBinding(ForegroundProperty, new Binding
{ {
Source = parentMap, Source = parentMap,
Path = new PropertyPath("Foreground") Path = new PropertyPath("Foreground")
}; });
SetBinding(ForegroundProperty, foregroundBinding);
} }
if (Stroke == null) if (Stroke == null)
{ {
strokeBinding = new Binding SetBinding(StrokeProperty, new Binding
{ {
Source = parentMap, Source = parentMap,
Path = new PropertyPath("Foreground") Path = new PropertyPath("Foreground")
}; });
SetBinding(StrokeProperty, strokeBinding);
} }
} }

View file

@ -46,9 +46,9 @@ namespace MapControl
{ {
foreach (UIElement element in Children) foreach (UIElement element in Children)
{ {
Location location; var location = GetLocation(element);
if (!(element is IMapShape) && (location = GetLocation(element)) != null) if (location != null)
{ {
ArrangeElementWithLocation(element); ArrangeElementWithLocation(element);
SetViewportPosition(element, parentMap, location); SetViewportPosition(element, parentMap, location);
@ -82,9 +82,9 @@ namespace MapControl
{ {
foreach (UIElement element in Children) foreach (UIElement element in Children)
{ {
Location location; var location = GetLocation(element);
if (!(element is IMapShape) && (location = GetLocation(element)) != null) if (location != null)
{ {
SetViewportPosition(element, parentMap, location); SetViewportPosition(element, parentMap, location);
} }
@ -109,14 +109,7 @@ namespace MapControl
private static void LocationPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) private static void LocationPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{ {
var element = (UIElement)obj; var element = (UIElement)obj;
var mapShape = element as IMapShape;
if (mapShape != null)
{
mapShape.LocationChanged((Location)e.OldValue, (Location)e.NewValue);
}
else
{
if (e.NewValue == null) if (e.NewValue == null)
{ {
ArrangeElementWithoutLocation(element, Size.Empty); ArrangeElementWithoutLocation(element, Size.Empty);
@ -128,7 +121,6 @@ namespace MapControl
SetViewportPosition(element, GetParentMap(element), (Location)e.NewValue); SetViewportPosition(element, GetParentMap(element), (Location)e.NewValue);
} }
}
private static void SetViewportPosition(UIElement element, MapBase parentMap, Location location) private static void SetViewportPosition(UIElement element, MapBase parentMap, Location location)
{ {
@ -146,13 +138,21 @@ namespace MapControl
Location.NearestLongitude(location.Longitude, parentMap.Center.Longitude))); Location.NearestLongitude(location.Longitude, parentMap.Center.Longitude)));
} }
if ((bool)element.GetValue(FrameworkElement.UseLayoutRoundingProperty)) if ((bool)element.GetValue(UseLayoutRoundingProperty))
{ {
viewportPosition.X = Math.Round(viewportPosition.X); viewportPosition.X = Math.Round(viewportPosition.X);
viewportPosition.Y = Math.Round(viewportPosition.Y); viewportPosition.Y = Math.Round(viewportPosition.Y);
} }
} }
var translateTransform = GetTranslateTransform(element);
translateTransform.X = viewportPosition.X;
translateTransform.Y = viewportPosition.Y;
}
private static TranslateTransform GetTranslateTransform(UIElement element)
{
var translateTransform = element.RenderTransform as TranslateTransform; var translateTransform = element.RenderTransform as TranslateTransform;
if (translateTransform == null) if (translateTransform == null)
@ -179,8 +179,7 @@ namespace MapControl
} }
} }
translateTransform.X = viewportPosition.X; return translateTransform;
translateTransform.Y = viewportPosition.Y;
} }
private static void ArrangeElementWithLocation(UIElement element) private static void ArrangeElementWithLocation(UIElement element)
@ -232,7 +231,7 @@ namespace MapControl
if (parentSize.IsEmpty) if (parentSize.IsEmpty)
{ {
var parent = frameworkElement.Parent as UIElement; var parent = frameworkElement.Parent as UIElement;
parentSize = parent != null ? parent.RenderSize : new Size(); parentSize = parent?.RenderSize ?? new Size();
} }
switch (frameworkElement.HorizontalAlignment) switch (frameworkElement.HorizontalAlignment)

View file

@ -12,8 +12,7 @@ namespace MapControl
{ {
public static readonly DependencyProperty DataProperty = DependencyProperty.Register( public static readonly DependencyProperty DataProperty = DependencyProperty.Register(
"Data", typeof(Geometry), typeof(MapPath), new FrameworkPropertyMetadata( "Data", typeof(Geometry), typeof(MapPath), new FrameworkPropertyMetadata(
null, FrameworkPropertyMetadataOptions.AffectsRender, null, FrameworkPropertyMetadataOptions.AffectsRender, DataPropertyChanged, CoerceDataProperty));
DataPropertyChanged, CoerceDataProperty));
static MapPath() static MapPath()
{ {
@ -40,7 +39,7 @@ namespace MapControl
private static void DataPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) private static void DataPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{ {
if (!object.ReferenceEquals(e.OldValue, e.NewValue)) if (!ReferenceEquals(e.OldValue, e.NewValue))
{ {
((MapPath)obj).UpdateData(); ((MapPath)obj).UpdateData();
} }

View file

@ -16,15 +16,24 @@ namespace MapControl
/// <summary> /// <summary>
/// Base class for map shapes. The shape geometry is given by the Data property, /// Base class for map shapes. The shape geometry is given by the Data property,
/// which must contain a Geometry defined in cartesian (projected) map coordinates. /// which must contain a Geometry defined in cartesian (projected) map coordinates.
/// The Stretch property is meaningless for MapPath, it will be reset to None. /// Optionally, the Location property can by set to adjust the viewport position to the
/// Optionally, the MapPanel.Location property can by set to move the viewport position /// visible map viewport, as done for elements where the MapPanel.Location property is set.
/// to a longitude with minimal distance to the longitude of the current map center.
/// </summary> /// </summary>
public partial class MapPath : IMapShape public partial class MapPath : IMapElement
{ {
public static readonly DependencyProperty LocationProperty = DependencyProperty.Register(
"Location", typeof(Location), typeof(MapPath),
new PropertyMetadata(null, (o, e) => ((MapPath)o).LocationChanged((Location)e.OldValue, (Location)e.NewValue)));
private readonly TransformGroup viewportTransform = new TransformGroup(); private readonly TransformGroup viewportTransform = new TransformGroup();
private MapBase parentMap; private MapBase parentMap;
public Location Location
{
get { return (Location)GetValue(LocationProperty); }
set { SetValue(LocationProperty, value); }
}
public TransformGroup ViewportTransform public TransformGroup ViewportTransform
{ {
get { return viewportTransform; } get { return viewportTransform; }
@ -35,11 +44,9 @@ namespace MapControl
get { return parentMap; } get { return parentMap; }
set set
{ {
var location = MapPanel.GetLocation(this); if (parentMap != null && Location != null)
if (parentMap != null && location != null)
{ {
parentMap.ViewportChanged -= OnViewportChanged; DetachViewportChanged();
} }
viewportTransform.Children.Clear(); viewportTransform.Children.Clear();
@ -49,11 +56,9 @@ namespace MapControl
{ {
viewportTransform.Children.Add(parentMap.ViewportTransform); viewportTransform.Children.Add(parentMap.ViewportTransform);
if (location != null) if (Location != null)
{ {
viewportTransform.Children.Insert(0, new TranslateTransform()); AttachViewportChanged();
parentMap.ViewportChanged += OnViewportChanged;
OnViewportChanged(this, EventArgs.Empty);
} }
} }
@ -69,42 +74,46 @@ namespace MapControl
} }
} }
void IMapShape.LocationChanged(Location oldValue, Location newValue) private void LocationChanged(Location oldValue, Location newValue)
{ {
if (parentMap != null) if (parentMap != null)
{ {
if (newValue == null) if (oldValue == null)
{
AttachViewportChanged();
}
else if (newValue == null)
{
DetachViewportChanged();
}
}
}
private void AttachViewportChanged()
{
viewportTransform.Children.Insert(0, new TranslateTransform());
parentMap.ViewportChanged += OnViewportChanged;
OnViewportChanged(parentMap, EventArgs.Empty);
}
private void DetachViewportChanged()
{ {
parentMap.ViewportChanged -= OnViewportChanged; parentMap.ViewportChanged -= OnViewportChanged;
viewportTransform.Children.RemoveAt(0); viewportTransform.Children.RemoveAt(0);
} }
else if (oldValue == null)
{
viewportTransform.Children.Insert(0, new TranslateTransform());
parentMap.ViewportChanged += OnViewportChanged;
OnViewportChanged(this, EventArgs.Empty);
}
}
}
private void OnViewportChanged(object sender, EventArgs e) private void OnViewportChanged(object sender, EventArgs e)
{ {
var location = MapPanel.GetLocation(this); var viewportPosition = parentMap.LocationToViewportPoint(Location);
if (parentMap != null && location != null)
{
var viewportPosition = parentMap.LocationToViewportPoint(location);
var longitudeOffset = 0d; var longitudeOffset = 0d;
if (viewportPosition.X < 0d || viewportPosition.X > parentMap.RenderSize.Width || if (viewportPosition.X < 0d || viewportPosition.X > parentMap.RenderSize.Width ||
viewportPosition.Y < 0d || viewportPosition.Y > parentMap.RenderSize.Height) viewportPosition.Y < 0d || viewportPosition.Y > parentMap.RenderSize.Height)
{ {
var longitude = Location.NormalizeLongitude(location.Longitude); longitudeOffset = Location.NearestLongitude(Location.Longitude, parentMap.Center.Longitude) - Location.Longitude;
longitudeOffset = Location.NearestLongitude(longitude, parentMap.Center.Longitude) - longitude;
} }
((TranslateTransform)viewportTransform.Children[0]).X = longitudeOffset; ((TranslateTransform)viewportTransform.Children[0]).X = longitudeOffset;
} }
} }
}
} }

View file

@ -22,14 +22,14 @@ namespace MapControl
public partial class MapPolyline : MapPath public partial class MapPolyline : MapPath
{ {
#if NETFX_CORE #if NETFX_CORE
// Binding fails on Windows Phone when property type is IEnumerable<Location> // Binding fails on Windows Runtime when property type is IEnumerable<Location>
public static readonly DependencyProperty LocationsProperty = DependencyProperty.Register( public static readonly DependencyProperty LocationsProperty = DependencyProperty.Register(
"Locations", typeof(IEnumerable), typeof(MapPolyline), "Locations", typeof(IEnumerable), typeof(MapPolyline),
new PropertyMetadata(null, LocationsPropertyChanged)); new PropertyMetadata(null, (o, e) => ((MapPolyline)o).LocationsChanged(e.OldValue as INotifyCollectionChanged, e.NewValue as INotifyCollectionChanged)));
#else #else
public static readonly DependencyProperty LocationsProperty = DependencyProperty.Register( public static readonly DependencyProperty LocationsProperty = DependencyProperty.Register(
"Locations", typeof(IEnumerable<Location>), typeof(MapPolyline), "Locations", typeof(IEnumerable<Location>), typeof(MapPolyline),
new PropertyMetadata(null, LocationsPropertyChanged)); new PropertyMetadata(null, (o, e) => ((MapPolyline)o).LocationsChanged(e.OldValue as INotifyCollectionChanged, e.NewValue as INotifyCollectionChanged)));
#endif #endif
public static readonly DependencyProperty IsClosedProperty = DependencyProperty.Register( public static readonly DependencyProperty IsClosedProperty = DependencyProperty.Register(
"IsClosed", typeof(bool), typeof(MapPolyline), "IsClosed", typeof(bool), typeof(MapPolyline),
@ -65,28 +65,24 @@ namespace MapControl
set { SetValue(FillRuleProperty, value); } set { SetValue(FillRuleProperty, value); }
} }
private void LocationCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) private void LocationsChanged(INotifyCollectionChanged oldCollection, INotifyCollectionChanged newCollection)
{ {
UpdateData();
}
private static void LocationsPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var mapPolyline = (MapPolyline)obj;
var oldCollection = e.OldValue as INotifyCollectionChanged;
var newCollection = e.NewValue as INotifyCollectionChanged;
if (oldCollection != null) if (oldCollection != null)
{ {
oldCollection.CollectionChanged -= mapPolyline.LocationCollectionChanged; oldCollection.CollectionChanged -= LocationCollectionChanged;
} }
if (newCollection != null) if (newCollection != null)
{ {
newCollection.CollectionChanged += mapPolyline.LocationCollectionChanged; newCollection.CollectionChanged += LocationCollectionChanged;
} }
mapPolyline.UpdateData(); UpdateData();
}
private void LocationCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
UpdateData();
} }
} }
} }

View file

@ -14,8 +14,8 @@ using System.Windows;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("© 2016 Clemens Fischer")] [assembly: AssemblyCopyright("© 2016 Clemens Fischer")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("2.11.0")] [assembly: AssemblyVersion("2.12.0")]
[assembly: AssemblyFileVersion("2.11.0")] [assembly: AssemblyFileVersion("2.12.0")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View file

@ -20,5 +20,11 @@ namespace MapControl
DefaultStyleKey = typeof(Pushpin); DefaultStyleKey = typeof(Pushpin);
MapPanel.AddParentMapHandlers(this); MapPanel.AddParentMapHandlers(this);
} }
public Location Location
{
get { return (Location)GetValue(MapPanel.LocationProperty); }
set { SetValue(MapPanel.LocationProperty, value); }
}
} }
} }

View file

@ -17,5 +17,14 @@ namespace MapControl
DefaultStyleKeyProperty.OverrideMetadata( DefaultStyleKeyProperty.OverrideMetadata(
typeof(Pushpin), new FrameworkPropertyMetadata(typeof(Pushpin))); typeof(Pushpin), new FrameworkPropertyMetadata(typeof(Pushpin)));
} }
public static readonly DependencyProperty LocationProperty =
MapPanel.LocationProperty.AddOwner(typeof(Pushpin));
public Location Location
{
get { return (Location)GetValue(LocationProperty); }
set { SetValue(LocationProperty, value); }
}
} }
} }

View file

@ -79,7 +79,7 @@ namespace MapControl
public virtual Uri GetUri(int x, int y, int zoomLevel) public virtual Uri GetUri(int x, int y, int zoomLevel)
{ {
return getUri != null ? getUri(x, y, zoomLevel) : null; return getUri?.Invoke(x, y, zoomLevel);
} }
private Uri GetBasicUri(int x, int y, int zoomLevel) private Uri GetBasicUri(int x, int y, int zoomLevel)

View file

@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("© 2016 Clemens Fischer")] [assembly: AssemblyCopyright("© 2016 Clemens Fischer")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("2.11.0")] [assembly: AssemblyVersion("2.12.0")]
[assembly: AssemblyFileVersion("2.11.0")] [assembly: AssemblyFileVersion("2.12.0")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View file

@ -17,11 +17,7 @@ namespace ViewModel
protected void RaisePropertyChanged(string propertyName) protected void RaisePropertyChanged(string propertyName)
{ {
var propertyChanged = PropertyChanged; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
if (propertyChanged != null)
{
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
} }
} }

View file

@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("© 2016 Clemens Fischer")] [assembly: AssemblyCopyright("© 2016 Clemens Fischer")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("2.11.0")] [assembly: AssemblyVersion("2.12.0")]
[assembly: AssemblyFileVersion("2.11.0")] [assembly: AssemblyFileVersion("2.12.0")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View file

@ -51,11 +51,7 @@ namespace PhoneApplication
private void RaisePropertyChanged(string propertyName) private void RaisePropertyChanged(string propertyName)
{ {
var propertyChanged = PropertyChanged; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
if (propertyChanged != null)
{
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
} }
private async void GeoLocatorStatusChanged(Geolocator sender, StatusChangedEventArgs args) private async void GeoLocatorStatusChanged(Geolocator sender, StatusChangedEventArgs args)

View file

@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("© 2016 Clemens Fischer")] [assembly: AssemblyCopyright("© 2016 Clemens Fischer")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("2.11.0")] [assembly: AssemblyVersion("2.12.0")]
[assembly: AssemblyFileVersion("2.11.0")] [assembly: AssemblyFileVersion("2.12.0")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View file

@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("© 2016 Clemens Fischer")] [assembly: AssemblyCopyright("© 2016 Clemens Fischer")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("2.11.0")] [assembly: AssemblyVersion("2.12.0")]
[assembly: AssemblyFileVersion("2.11.0")] [assembly: AssemblyFileVersion("2.12.0")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View file

@ -88,37 +88,26 @@
<VisualStateGroup x:Name="CommonStates"> <VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/> <VisualState x:Name="Normal"/>
<VisualState x:Name="Disabled"/> <VisualState x:Name="Disabled"/>
<VisualState x:Name="PointerOver"> <VisualState x:Name="PointerOver"/>
<Storyboard> <VisualState x:Name="Pressed"/>
<DoubleAnimation Storyboard.TargetName="labelBackground" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.1"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Unselected"/>
<VisualState x:Name="Selected"> <VisualState x:Name="Selected">
<Storyboard> <Storyboard>
<DoubleAnimation Storyboard.TargetName="selectedPath" Storyboard.TargetProperty="Opacity" To="0.7" Duration="0:0:0.1"/> <DoubleAnimation Storyboard.TargetName="selectedPath" Storyboard.TargetProperty="Opacity" To="0.75" Duration="0"/>
</Storyboard> </Storyboard>
</VisualState> </VisualState>
<VisualState x:Name="SelectedUnfocus"> <VisualState x:Name="SelectedUnfocused">
<Storyboard> <Storyboard>
<DoubleAnimation Storyboard.TargetName="selectedPath" Storyboard.TargetProperty="Opacity" To="0.7" Duration="0:0:0.1"/> <DoubleAnimation Storyboard.TargetName="selectedPath" Storyboard.TargetProperty="Opacity" To="0.75" Duration="0"/>
</Storyboard> </Storyboard>
</VisualState> </VisualState>
<VisualState x:Name="SelectedDisable"> <VisualState x:Name="SelectedPointerOver">
<Storyboard> <Storyboard>
<DoubleAnimation Storyboard.TargetName="selectedPath" Storyboard.TargetProperty="Opacity" To="0.7" Duration="0:0:0.1"/> <DoubleAnimation Storyboard.TargetName="selectedPath" Storyboard.TargetProperty="Opacity" To="0.75" Duration="0"/>
</Storyboard>
</VisualState>
<VisualState x:Name="SelectedPointer">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="selectedPath" Storyboard.TargetProperty="Opacity" To="0.7" Duration="0:0:0.1"/>
</Storyboard> </Storyboard>
</VisualState> </VisualState>
<VisualState x:Name="SelectedPressed"> <VisualState x:Name="SelectedPressed">
<Storyboard> <Storyboard>
<DoubleAnimation Storyboard.TargetName="selectedPath" Storyboard.TargetProperty="Opacity" To="0.7" Duration="0:0:0.1"/> <DoubleAnimation Storyboard.TargetName="selectedPath" Storyboard.TargetProperty="Opacity" To="0.75" Duration="0"/>
</Storyboard> </Storyboard>
</VisualState> </VisualState>
</VisualStateGroup> </VisualStateGroup>

View file

@ -12,7 +12,7 @@ namespace UniversalApp
//TileImageLoader.Cache = new MapControl.Caching.ImageFileCache(); //TileImageLoader.Cache = new MapControl.Caching.ImageFileCache();
//TileImageLoader.Cache = new MapControl.Caching.FileDbCache(); //TileImageLoader.Cache = new MapControl.Caching.FileDbCache();
this.InitializeComponent(); InitializeComponent();
} }
private void ImageOpacitySliderValueChanged(object sender, RangeBaseValueChangedEventArgs e) private void ImageOpacitySliderValueChanged(object sender, RangeBaseValueChangedEventArgs e)

View file

@ -8,7 +8,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCopyright("© 2016 Clemens Fischer")] [assembly: AssemblyCopyright("© 2016 Clemens Fischer")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: AssemblyVersion("2.11.0")] [assembly: AssemblyVersion("2.12.0")]
[assembly: AssemblyFileVersion("2.11.0")] [assembly: AssemblyFileVersion("2.12.0")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]

View file

@ -96,7 +96,7 @@
<Style x:Key="PointItemStyle" TargetType="map:MapItem"> <Style x:Key="PointItemStyle" TargetType="map:MapItem">
<EventSetter Event="TouchDown" Handler="MapItemTouchDown"/> <EventSetter Event="TouchDown" Handler="MapItemTouchDown"/>
<Setter Property="map:MapPanel.Location" Value="{Binding Location}"/> <Setter Property="Location" Value="{Binding Location}"/>
<Setter Property="Foreground" Value="Black"/> <Setter Property="Foreground" Value="Black"/>
<Setter Property="Template"> <Setter Property="Template">
<Setter.Value> <Setter.Value>
@ -151,7 +151,7 @@
<Style x:Key="PushpinItemStyle" TargetType="map:MapItem"> <Style x:Key="PushpinItemStyle" TargetType="map:MapItem">
<EventSetter Event="TouchDown" Handler="MapItemTouchDown"/> <EventSetter Event="TouchDown" Handler="MapItemTouchDown"/>
<Setter Property="map:MapPanel.Location" Value="{Binding Location}"/> <Setter Property="Location" Value="{Binding Location}"/>
<Setter Property="VerticalAlignment" Value="Bottom"/> <Setter Property="VerticalAlignment" Value="Bottom"/>
<Setter Property="Foreground" Value="Black"/> <Setter Property="Foreground" Value="Black"/>
<Setter Property="Visibility"> <Setter Property="Visibility">
@ -233,7 +233,7 @@
</map:MapPath.Data> </map:MapPath.Data>
</map:MapPath> </map:MapPath>
<map:Pushpin map:MapPanel.Location="53.5,8.2" Background="Yellow" Foreground="Blue" Content="N 53° 30' E 8° 12'"> <map:Pushpin Location="53.5,8.2" Background="Yellow" Foreground="Blue" Content="N 53° 30' E 8° 12'">
<map:Pushpin.Visibility> <map:Pushpin.Visibility>
<MultiBinding Converter="{StaticResource LocationToVisibilityConverter}"> <MultiBinding Converter="{StaticResource LocationToVisibilityConverter}">
<Binding Path="(map:MapPanel.ParentMap)" RelativeSource="{RelativeSource Self}"/> <Binding Path="(map:MapPanel.ParentMap)" RelativeSource="{RelativeSource Self}"/>

View file

@ -7,8 +7,8 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCompany("Clemens Fischer")] [assembly: AssemblyCompany("Clemens Fischer")]
[assembly: AssemblyCopyright("© 2016 Clemens Fischer")] [assembly: AssemblyCopyright("© 2016 Clemens Fischer")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("2.11.0")] [assembly: AssemblyVersion("2.12.0")]
[assembly: AssemblyFileVersion("2.11.0")] [assembly: AssemblyFileVersion("2.12.0")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]