Simplified layout in MapPanel, replaced ViewportPosition by Point?.

This commit is contained in:
ClemensF 2012-08-26 21:54:00 +02:00
parent e7f78df179
commit d055d737ed
9 changed files with 89 additions and 120 deletions

View file

@ -68,7 +68,6 @@
<Compile Include="TileLayer.cs" />
<Compile Include="TileLayerCollection.cs" />
<Compile Include="TileSource.cs" />
<Compile Include="ViewportPosition.cs" />
</ItemGroup>
<ItemGroup>
<Page Include="Themes\Generic.xaml">

View file

@ -19,12 +19,6 @@ namespace MapControl
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits, ParentMapPropertyChanged));
}
protected MapElement()
{
HorizontalAlignment = HorizontalAlignment.Stretch;
VerticalAlignment = VerticalAlignment.Stretch;
}
public Map ParentMap
{
get { return MapPanel.GetParentMap(this); }

View file

@ -128,12 +128,12 @@ namespace MapControl
}
else if ((selectedContainer = GetContainer(SelectedItem)) != null)
{
ViewportPosition p1 = MapPanel.GetViewportPosition(selectedContainer);
ViewportPosition p2 = MapPanel.GetViewportPosition(container);
Point? p1 = MapPanel.GetViewportPosition(selectedContainer);
Point? p2 = MapPanel.GetViewportPosition(container);
if (p1 != null && p2 != null)
if (p1.HasValue && p2.HasValue)
{
Rect rect = new Rect(p1.Position, p2.Position);
Rect rect = new Rect(p1.Value, p2.Value);
BeginUpdateSelectedItems();
SelectedItems.Clear();
@ -237,21 +237,21 @@ namespace MapControl
private bool IsItemInGeometry(object item, Geometry geometry)
{
UIElement container = GetContainer(item);
ViewportPosition viewportPosition;
Point? viewportPosition;
return container != null
&& (viewportPosition = MapPanel.GetViewportPosition(container)) != null
&& geometry.FillContains(viewportPosition.Position);
&& (viewportPosition = MapPanel.GetViewportPosition(container)).HasValue
&& geometry.FillContains(viewportPosition.Value);
}
private bool IsItemInRect(object item, Rect rect)
{
UIElement container = GetContainer(item);
ViewportPosition viewportPosition;
Point? viewportPosition;
return container != null
&& (viewportPosition = MapPanel.GetViewportPosition(container)) != null
&& rect.Contains(viewportPosition.Position);
&& (viewportPosition = MapPanel.GetViewportPosition(container)).HasValue
&& rect.Contains(viewportPosition.Value);
}
}
}

View file

@ -4,15 +4,13 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace MapControl
{
/// <summary>
/// Positions child elements on a Map. A child element's position is specified by the
/// attached property Location, given as geographic location with latitude and longitude.
/// The attached property ViewportPosition gets a child element's position in viewport
/// coordinates and indicates if the coordinates are located inside the bounds of the ParentMap.
/// The attached property ViewportPosition gets a child element's position in viewport coordinates.
/// </summary>
public class MapPanel : Panel
{
@ -23,7 +21,7 @@ namespace MapControl
public static readonly DependencyProperty ParentMapProperty = ParentMapPropertyKey.DependencyProperty;
private static readonly DependencyPropertyKey ViewportPositionPropertyKey = DependencyProperty.RegisterAttachedReadOnly(
"ViewportPosition", typeof(ViewportPosition), typeof(MapPanel),
"ViewportPosition", typeof(Point?), typeof(MapPanel),
new FrameworkPropertyMetadata(ViewportPositionPropertyChanged));
public static readonly DependencyProperty ViewportPositionProperty = ViewportPositionPropertyKey.DependencyProperty;
@ -47,9 +45,9 @@ namespace MapControl
return (Map)element.GetValue(ParentMapProperty);
}
public static ViewportPosition GetViewportPosition(UIElement element)
public static Point? GetViewportPosition(UIElement element)
{
return (ViewportPosition)element.GetValue(ViewportPositionProperty);
return (Point?)element.GetValue(ViewportPositionProperty);
}
public static Location GetLocation(UIElement element)
@ -78,22 +76,21 @@ namespace MapControl
{
foreach (UIElement element in InternalChildren)
{
ViewportPosition viewportPosition = GetViewportPosition(element);
Point? viewportPosition = GetViewportPosition(element);
if (viewportPosition == null || !ArrangeElement(element, viewportPosition))
if (viewportPosition.HasValue)
{
ArrangeElement(element, finalSize);
ArrangeElement(element, viewportPosition.Value);
}
else
{
element.Arrange(new Rect(finalSize));
}
}
return finalSize;
}
protected virtual Point GetArrangePosition(ViewportPosition viewportPosition)
{
return viewportPosition.Position;
}
protected virtual void OnViewportChanged()
{
Map parentMap = ParentMap;
@ -136,11 +133,11 @@ namespace MapControl
if (element != null)
{
ViewportPosition position = (ViewportPosition)e.NewValue;
Point? viewportPosition = (Point?)e.NewValue;
if (position != null)
if (viewportPosition.HasValue)
{
ArrangeElement(element, position);
ArrangeElement(element, viewportPosition.Value);
}
else
{
@ -161,36 +158,23 @@ namespace MapControl
private static void SetViewportPosition(UIElement element, Map parentMap, Location location)
{
ViewportPosition viewportPosition = null;
Point? viewportPosition = null;
if (parentMap != null && location != null)
{
Point position = parentMap.LocationToViewportPoint(location);
viewportPosition = new ViewportPosition(position,
position.X >= 0d && position.X <= parentMap.ActualWidth &&
position.Y >= 0d && position.Y <= parentMap.ActualHeight);
viewportPosition = parentMap.LocationToViewportPoint(location);
}
element.SetValue(ViewportPositionPropertyKey, viewportPosition);
}
private static bool ArrangeElement(UIElement element, ViewportPosition viewportPosition)
private static void ArrangeElement(UIElement element, Point position)
{
MapPanel panel = VisualTreeHelper.GetParent(element) as MapPanel;
Point position = panel != null ? panel.GetArrangePosition(viewportPosition) : viewportPosition.Position;
Rect rect = new Rect(position, element.DesiredSize);
FrameworkElement frameworkElement = element as FrameworkElement;
if (frameworkElement != null)
if (element is FrameworkElement)
{
if (frameworkElement.HorizontalAlignment == HorizontalAlignment.Stretch ||
frameworkElement.VerticalAlignment == VerticalAlignment.Stretch)
{
return false; // do not arrange at position
}
switch (frameworkElement.HorizontalAlignment)
switch (((FrameworkElement)element).HorizontalAlignment)
{
case HorizontalAlignment.Center:
rect.X -= rect.Width / 2d;
@ -198,11 +182,14 @@ namespace MapControl
case HorizontalAlignment.Right:
rect.X -= rect.Width;
break;
case HorizontalAlignment.Stretch:
rect.X = 0d;
break;
default:
break;
}
switch (frameworkElement.VerticalAlignment)
switch (((FrameworkElement)element).VerticalAlignment)
{
case VerticalAlignment.Center:
rect.Y -= rect.Height / 2d;
@ -210,47 +197,8 @@ namespace MapControl
case VerticalAlignment.Bottom:
rect.Y -= rect.Height;
break;
default:
break;
}
}
element.Arrange(rect);
return true;
}
private static void ArrangeElement(UIElement element, Size panelSize)
{
Rect rect = new Rect(element.DesiredSize);
FrameworkElement frameworkElement = element as FrameworkElement;
if (frameworkElement != null)
{
switch (frameworkElement.HorizontalAlignment)
{
case HorizontalAlignment.Center:
rect.X = (panelSize.Width - rect.Width) / 2d;
break;
case HorizontalAlignment.Right:
rect.X = panelSize.Width - rect.Width;
break;
case HorizontalAlignment.Stretch:
rect.Width = panelSize.Width;
break;
default:
break;
}
switch (frameworkElement.VerticalAlignment)
{
case VerticalAlignment.Center:
rect.Y = (panelSize.Height - rect.Height) / 2d;
break;
case VerticalAlignment.Bottom:
rect.Y = panelSize.Height - rect.Height;
break;
case VerticalAlignment.Stretch:
rect.Height = panelSize.Height;
rect.Y = 0d;
break;
default:
break;

View file

@ -11,6 +11,8 @@
</Setter>
</Style>
<Style x:Key="{x:Type map:MapItem}" TargetType="{x:Type map:MapItem}">
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type map:MapItem}">

View file

@ -1,23 +0,0 @@
// WPF MapControl - http://wpfmapcontrol.codeplex.com/
// Copyright © 2012 Clemens Fischer
// Licensed under the Microsoft Public License (Ms-PL)
using System.Windows;
namespace MapControl
{
/// <summary>
/// Viewport position of a MapPanel child element.
/// </summary>
public class ViewportPosition
{
public ViewportPosition(Point position, bool isInside)
{
Position = position;
IsInside = isInside;
}
public Point Position { get; private set; }
public bool IsInside { get; private set; }
}
}

View file

@ -46,7 +46,7 @@
<local:SampleItemCollection x:Key="Polylines"/>
<local:SampleItemCollection x:Key="Points"/>
<local:SampleItemCollection x:Key="Pushpins"/>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<local:ViewportPositionToVisibilityConverter x:Key="ViewportPositionToVisibilityConverter"/>
<DataTemplate x:Key="PolylineItemTemplate">
<map:MapPolyline Locations="{Binding Locations}" Stroke="Red" StrokeThickness="3"/>
</DataTemplate>
@ -100,7 +100,14 @@
</Style>
<Style x:Key="PushpinItemStyle" TargetType="map:MapItem">
<Setter Property="map:MapPanel.Location" Value="{Binding Location}"/>
<Setter Property="Visibility" Value="{Binding (map:MapPanel.ViewportPosition).IsInside, Converter={StaticResource BooleanToVisibilityConverter}, RelativeSource={RelativeSource Self}}"/>
<Setter Property="Visibility">
<Setter.Value>
<MultiBinding Converter="{StaticResource ViewportPositionToVisibilityConverter}">
<Binding Path="(map:MapPanel.ParentMap)" RelativeSource="{RelativeSource Self}"/>
<Binding Path="(map:MapPanel.ViewportPosition)" RelativeSource="{RelativeSource Self}"/>
</MultiBinding>
</Setter.Value>
</Setter>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Bottom"/>
<Setter Property="Template">
@ -137,8 +144,14 @@
<map:MapItemsControl ItemsSource="{StaticResource Pushpins}"
ItemContainerStyle="{StaticResource PushpinItemStyle}"
IsSynchronizedWithCurrentItem="True"/>
<map:Pushpin Location="53.5,8.2" Background="Yellow" Foreground="Blue" Content="N 53° 30' E 8° 12'"
Visibility="{Binding (map:MapPanel.ViewportPosition).IsInside, Converter={StaticResource BooleanToVisibilityConverter}, RelativeSource={RelativeSource Self}}"/>
<map:Pushpin Location="53.5,8.2" Background="Yellow" Foreground="Blue" Content="N 53° 30' E 8° 12'">
<map:Pushpin.Visibility>
<MultiBinding Converter="{StaticResource ViewportPositionToVisibilityConverter}">
<Binding Path="(map:MapPanel.ParentMap)" RelativeSource="{RelativeSource Self}"/>
<Binding Path="(map:MapPanel.ViewportPosition)" RelativeSource="{RelativeSource Self}"/>
</MultiBinding>
</map:Pushpin.Visibility>
</map:Pushpin>
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="2,0,0,0" FontSize="10"
Text="{Binding BaseTileLayer.Description, ElementName=map}"/>
</map:Map>

View file

@ -60,6 +60,7 @@
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
<Compile Include="SampleItems.cs" />
<Compile Include="ViewportPositionToVisibilityConverter.cs" />
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>

View file

@ -0,0 +1,35 @@
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using MapControl;
namespace SampleApplication
{
public class ViewportPositionToVisibilityConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
Visibility visibility = Visibility.Visible;
if (values.Length == 2 && values[0] is Map && values[1] is Point? && ((Point?)values[1]).HasValue)
{
Map parentMap = (Map)values[0];
Point position = ((Point?)values[1]).Value;
if (position.X < 0d || position.X > parentMap.ActualWidth ||
position.Y < 0d || position.Y > parentMap.ActualHeight)
{
visibility = Visibility.Hidden;
}
}
return visibility;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
}