mirror of
https://github.com/ClemensFischer/XAML-Map-Control.git
synced 2026-04-04 22:18:56 +00:00
Reworked sample applications
This commit is contained in:
parent
9ce981a6ee
commit
32491a8e31
22 changed files with 947 additions and 706 deletions
|
|
@ -5,147 +5,114 @@
|
|||
xmlns:local="clr-namespace:SampleApplication"
|
||||
Title="XAML MapControl - WPF Sample Application" Height="600" Width="900"
|
||||
Stylus.IsPressAndHoldEnabled="False">
|
||||
<Window.Resources>
|
||||
<DataTemplate x:Key="PolylineItemTemplate">
|
||||
<map:MapPolyline Locations="{Binding Locations}" Stroke="Red" StrokeThickness="3"/>
|
||||
</DataTemplate>
|
||||
|
||||
<Style x:Key="PolylineItemStyle" TargetType="map:MapItem">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="map:MapItem">
|
||||
<map:MapPolyline Locations="{Binding Locations}" Stroke="Red" StrokeThickness="3"/>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="PointItemStyle" TargetType="map:MapItem">
|
||||
<EventSetter Event="TouchDown" Handler="MapItemTouchDown"/>
|
||||
<Setter Property="AutoCollapse" Value="True"/>
|
||||
<Setter Property="Location" Value="{Binding Location}"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="map:MapItem">
|
||||
<Canvas>
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal"/>
|
||||
<VisualState x:Name="Disabled"/>
|
||||
<VisualState x:Name="MouseOver">
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="hoverPath"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
To="0.7" Duration="0:0:0.1"/>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
<VisualStateGroup x:Name="SelectionStates">
|
||||
<VisualState x:Name="Unselected"/>
|
||||
<VisualState x:Name="Selected">
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="selectedPath"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
To="0.7" Duration="0:0:0.1"/>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
<Path x:Name="selectedPath" Fill="White" Opacity="0">
|
||||
<Path.Data>
|
||||
<EllipseGeometry RadiusX="12" RadiusY="12"/>
|
||||
</Path.Data>
|
||||
</Path>
|
||||
<Path x:Name="hoverPath" StrokeThickness="6" Stroke="White" Opacity="0">
|
||||
<Path.Data>
|
||||
<EllipseGeometry RadiusX="8" RadiusY="8"/>
|
||||
</Path.Data>
|
||||
</Path>
|
||||
<Path StrokeThickness="2" Stroke="Gray" Fill="Transparent">
|
||||
<Path.Data>
|
||||
<EllipseGeometry RadiusX="8" RadiusY="8"/>
|
||||
</Path.Data>
|
||||
</Path>
|
||||
<Grid Canvas.Left="15" Canvas.Top="-8">
|
||||
<local:OutlinedText Margin="1" OutlineThickness="1.5" Text="{Binding Name}"
|
||||
Background="{Binding Background, RelativeSource={RelativeSource AncestorType=map:MapBase}}"/>
|
||||
</Grid>
|
||||
</Canvas>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsSelected" Value="True">
|
||||
<Setter Property="Panel.ZIndex" Value="1"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="PushpinItemStyle" TargetType="map:MapItem">
|
||||
<EventSetter Event="TouchDown" Handler="MapItemTouchDown"/>
|
||||
<Setter Property="AutoCollapse" Value="True"/>
|
||||
<Setter Property="Location" Value="{Binding Location}"/>
|
||||
<Setter Property="VerticalAlignment" Value="Bottom"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="map:MapItem">
|
||||
<map:Pushpin Content="{Binding Name}"/>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsSelected" Value="True">
|
||||
<Setter Property="Panel.ZIndex" Value="1"/>
|
||||
<Setter Property="Foreground" Value="OrangeRed"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
|
||||
|
||||
<map:WebMercatorProjection x:Key="WebMercatorProjection"/>
|
||||
<map:WorldMercatorProjection x:Key="WorldMercatorProjection"/>
|
||||
<map:EquirectangularProjection x:Key="EquirectangularProjection"/>
|
||||
<map:OrthographicProjection x:Key="OrthographicProjection"/>
|
||||
<map:GnomonicProjection x:Key="GnomonicProjection"/>
|
||||
<map:StereographicProjection x:Key="StereographicProjection"/>
|
||||
</Window.Resources>
|
||||
|
||||
<Window.DataContext>
|
||||
<local:MapViewModel/>
|
||||
</Window.DataContext>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.Resources>
|
||||
<DataTemplate DataType="{x:Type local:PolylineItem}">
|
||||
<map:MapPolyline Locations="{Binding Locations}" Stroke="Red" StrokeThickness="3"/>
|
||||
</DataTemplate>
|
||||
|
||||
<Style x:Key="PointItemStyle" TargetType="map:MapItem">
|
||||
<EventSetter Event="TouchDown" Handler="MapItemTouchDown"/>
|
||||
<Setter Property="AutoCollapse" Value="True"/>
|
||||
<Setter Property="Location" Value="{Binding Location}"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="map:MapItem">
|
||||
<Canvas>
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="CommonStates">
|
||||
<VisualState x:Name="Normal"/>
|
||||
<VisualState x:Name="Disabled"/>
|
||||
<VisualState x:Name="MouseOver">
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="hoverPath"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
To="0.7" Duration="0:0:0.1"/>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
<VisualStateGroup x:Name="SelectionStates">
|
||||
<VisualState x:Name="Unselected"/>
|
||||
<VisualState x:Name="Selected">
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="selectedPath"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
To="0.7" Duration="0:0:0.1"/>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
<Path x:Name="selectedPath" Fill="White" Opacity="0">
|
||||
<Path.Data>
|
||||
<EllipseGeometry RadiusX="12" RadiusY="12"/>
|
||||
</Path.Data>
|
||||
</Path>
|
||||
<Path x:Name="hoverPath" StrokeThickness="6" Stroke="White" Opacity="0">
|
||||
<Path.Data>
|
||||
<EllipseGeometry RadiusX="8" RadiusY="8"/>
|
||||
</Path.Data>
|
||||
</Path>
|
||||
<Path StrokeThickness="2" Stroke="Gray" Fill="Transparent">
|
||||
<Path.Data>
|
||||
<EllipseGeometry RadiusX="8" RadiusY="8"/>
|
||||
</Path.Data>
|
||||
</Path>
|
||||
<Grid Canvas.Left="15" Canvas.Top="-8">
|
||||
<local:OutlinedText Margin="1" OutlineThickness="1.5" Text="{Binding Name}"
|
||||
Background="{Binding Background, RelativeSource={RelativeSource AncestorType=map:MapBase}}"/>
|
||||
</Grid>
|
||||
</Canvas>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsSelected" Value="True">
|
||||
<Setter Property="Panel.ZIndex" Value="1"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="PushpinItemStyle" TargetType="map:MapItem">
|
||||
<EventSetter Event="TouchDown" Handler="MapItemTouchDown"/>
|
||||
<Setter Property="AutoCollapse" Value="True"/>
|
||||
<Setter Property="Location" Value="{Binding Location}"/>
|
||||
<Setter Property="VerticalAlignment" Value="Bottom"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="map:MapItem">
|
||||
<map:Pushpin Content="{Binding Name}"/>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsSelected" Value="True">
|
||||
<Setter Property="Panel.ZIndex" Value="1"/>
|
||||
<Setter Property="Foreground" Value="OrangeRed"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<map:WebMercatorProjection x:Key="WebMercatorProjection"/>
|
||||
<map:WorldMercatorProjection x:Key="WorldMercatorProjection"/>
|
||||
<map:EquirectangularProjection x:Key="EquirectangularProjection"/>
|
||||
<map:OrthographicProjection x:Key="OrthographicProjection"/>
|
||||
<map:GnomonicProjection x:Key="GnomonicProjection"/>
|
||||
<map:StereographicProjection x:Key="StereographicProjection"/>
|
||||
</Grid.Resources>
|
||||
|
||||
<Grid.DataContext>
|
||||
<local:MapViewModel/>
|
||||
</Grid.DataContext>
|
||||
|
||||
<map:Map x:Name="map" ZoomLevel="11" MaxZoomLevel="21" MouseWheelZoomDelta="1"
|
||||
Center="{Binding MapCenter}"
|
||||
MapLayer="{Binding MapLayers.CurrentMapLayer}"
|
||||
MapProjection="{Binding SelectedValue, ElementName=projectionComboBox,
|
||||
FallbackValue={StaticResource WebMercatorProjection},
|
||||
TargetNullValue={StaticResource WebMercatorProjection}}"
|
||||
Center="53.5,8.2"
|
||||
MapLayer="{Binding MapLayers[OpenStreetMap]}"
|
||||
MouseLeftButtonDown="MapMouseLeftButtonDown"
|
||||
MouseRightButtonDown="MapMouseRightButtonDown"
|
||||
MouseMove="MapMouseMove" MouseLeave="MapMouseLeave"
|
||||
ManipulationInertiaStarting="MapManipulationInertiaStarting">
|
||||
|
||||
<Image Source="10_535_330.jpg" Stretch="Fill"
|
||||
Opacity="{Binding Value, ElementName=imageOpacitySlider}"
|
||||
map:MapPanel.BoundingBox="53.54031,8.08594,53.74871,8.43750"/>
|
||||
|
||||
<map:MapGraticule x:Name="graticule" Opacity="0.6"
|
||||
Visibility="{Binding IsChecked, ElementName=graticuleCheckBox,
|
||||
Converter={StaticResource BooleanToVisibilityConverter}}"/>
|
||||
|
||||
<map:MapScale HorizontalAlignment="Left" VerticalAlignment="Bottom"/>
|
||||
|
||||
<!-- use ItemTemplate or ItemContainerStyle alternatively -->
|
||||
<map:MapItemsControl ItemsSource="{Binding Polylines}"
|
||||
ItemTemplate="{StaticResource PolylineItemTemplate}"/>
|
||||
<!--<map:MapItemsControl ItemsSource="{Binding Polylines}"
|
||||
ItemContainerStyle="{StaticResource PolylineItemStyle}"/>-->
|
||||
<map:MapItemsControl ItemsSource="{Binding Polylines}"/>
|
||||
|
||||
<map:MapItemsControl ItemsSource="{Binding Points}"
|
||||
ItemContainerStyle="{StaticResource PointItemStyle}"
|
||||
|
|
@ -169,58 +136,34 @@
|
|||
</map:Map>
|
||||
|
||||
<Border HorizontalAlignment="Right" VerticalAlignment="Bottom" Background="#AFFFFFFF">
|
||||
<TextBlock Margin="4,2" FontSize="10" local:HyperlinkText.InlinesSource="{Binding MapLayer.Description, ElementName=map}"/>
|
||||
<TextBlock Margin="4,2" FontSize="10"
|
||||
local:HyperlinkText.InlinesSource="{Binding MapLayer.Description, ElementName=map}"/>
|
||||
</Border>
|
||||
|
||||
<Grid Grid.Row="1">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock x:Name="mouseLocation" Margin="5" VerticalAlignment="Bottom" FontFamily="Segoe UI Mono"/>
|
||||
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<StackPanel Margin="5">
|
||||
<TextBlock Text="Zoom Level" Margin="0,0,0,2" HorizontalAlignment="Center" FontSize="10"/>
|
||||
<Slider AutoToolTipPlacement="TopLeft" AutoToolTipPrecision="0"
|
||||
Width="75" VerticalAlignment="Center" SmallChange="0.01"
|
||||
Minimum="{Binding MinZoomLevel, ElementName=map}"
|
||||
Maximum="{Binding MaxZoomLevel, ElementName=map}"
|
||||
Value="{Binding TargetZoomLevel, ElementName=map}"/>
|
||||
</StackPanel>
|
||||
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Margin="6">
|
||||
<local:MapLayersMenuButton
|
||||
Margin="2" Padding="6" FontSize="16" ToolTip="Map Layers and Overlays"
|
||||
Map="{Binding ElementName=map}"
|
||||
MapLayers="{Binding MapLayers}"
|
||||
MapOverlays="{Binding MapOverlays}"/>
|
||||
|
||||
<StackPanel Margin="5">
|
||||
<TextBlock Text="Heading" Margin="0,0,0,2" HorizontalAlignment="Center" FontSize="10"/>
|
||||
<Slider AutoToolTipPlacement="TopLeft" AutoToolTipPrecision="0"
|
||||
Width="75" VerticalAlignment="Center" SmallChange="5" LargeChange="45"
|
||||
Minimum="0" Maximum="360" Value="{Binding TargetHeading, ElementName=map}"/>
|
||||
</StackPanel>
|
||||
<!--<local:MapProjectionsMenuButton
|
||||
Margin="2" Padding="6" FontSize="16" ToolTip="Map Projections"
|
||||
Map="{Binding ElementName=map}"
|
||||
MapProjections="{Binding MapProjections}"/>-->
|
||||
|
||||
<StackPanel Margin="5">
|
||||
<TextBlock Text="Image Opacity" Margin="0,0,0,2" HorizontalAlignment="Center" FontSize="10"/>
|
||||
<Slider x:Name="imageOpacitySlider" AutoToolTipPlacement="TopLeft" AutoToolTipPrecision="1"
|
||||
Width="75" VerticalAlignment="Center" Minimum="0" Maximum="1" Value="0.5"/>
|
||||
</StackPanel>
|
||||
<Slider Orientation="Vertical" Margin="8" Height="100"
|
||||
Minimum="{Binding MinZoomLevel, ElementName=map}"
|
||||
Maximum="{Binding MaxZoomLevel, ElementName=map}"
|
||||
Value="{Binding TargetZoomLevel, ElementName=map}"
|
||||
SmallChange="0.1"
|
||||
AutoToolTipPlacement="BottomRight" AutoToolTipPrecision="0"/>
|
||||
</StackPanel>
|
||||
|
||||
<CheckBox x:Name="graticuleCheckBox" ToolTip="Graticule Overlay" Margin="8"
|
||||
VerticalAlignment="Bottom" Content="Graticule"/>
|
||||
|
||||
<CheckBox ToolTip="Seamarks Overlay" Margin="8" VerticalAlignment="Bottom" Content="Seamarks"
|
||||
Checked="SeamarksChecked" Unchecked="SeamarksUnchecked"/>
|
||||
|
||||
<ComboBox ToolTip="Map Layer" Width="200" Margin="5" VerticalAlignment="Bottom"
|
||||
ItemsSource="{Binding MapLayers.MapLayerNames}"
|
||||
SelectedItem="{Binding MapLayers.CurrentMapLayerName}"/>
|
||||
|
||||
<ComboBox x:Name="projectionComboBox" ToolTip="Map Projection" Width="120" Margin="5" VerticalAlignment="Bottom"
|
||||
SelectedValuePath="Tag" SelectedIndex="0">
|
||||
<ComboBoxItem Content="Web Mercator" Tag="{StaticResource WebMercatorProjection}"/>
|
||||
<ComboBoxItem Content="World Mercator" Tag="{StaticResource WorldMercatorProjection}"/>
|
||||
<ComboBoxItem Content="Equirectangular" Tag="{StaticResource EquirectangularProjection}"/>
|
||||
<ComboBoxItem Content="Orthographic" Tag="{StaticResource OrthographicProjection}"/>
|
||||
<ComboBoxItem Content="Gnomonic" Tag="{StaticResource GnomonicProjection}"/>
|
||||
<ComboBoxItem Content="Stereographic" Tag="{StaticResource StereographicProjection}"/>
|
||||
</ComboBox>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<local:OutlinedText
|
||||
x:Name="mouseLocation" Margin="4"
|
||||
Background="{Binding Background, ElementName=map}"
|
||||
Foreground="{Binding Foreground, ElementName=map}"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top"/>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
using System;
|
||||
using MapControl;
|
||||
using MapControl.Caching;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using MapControl;
|
||||
using MapControl.Caching;
|
||||
|
||||
namespace SampleApplication
|
||||
{
|
||||
|
|
@ -108,15 +108,5 @@ namespace SampleApplication
|
|||
mapItem.IsSelected = !mapItem.IsSelected;
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void SeamarksChecked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
map.Children.Insert(map.Children.IndexOf(graticule), ((MapViewModel)DataContext).MapLayers.SeamarksLayer);
|
||||
}
|
||||
|
||||
private void SeamarksUnchecked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
map.Children.Remove(((MapViewModel)DataContext).MapLayers.SeamarksLayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.Windows;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
|
||||
|
|
@ -6,36 +7,49 @@ namespace SampleApplication
|
|||
{
|
||||
public class OutlinedText : FrameworkElement
|
||||
{
|
||||
private GlyphRun glyphRun;
|
||||
private FormattedText text;
|
||||
private Geometry outline;
|
||||
|
||||
public static readonly DependencyProperty TextProperty = TextBlock.TextProperty.AddOwner(
|
||||
typeof(OutlinedText), new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).glyphRun = null) { AffectsMeasure = true });
|
||||
typeof(OutlinedText),
|
||||
new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).text = null) { AffectsMeasure = true });
|
||||
|
||||
public static readonly DependencyProperty FontSizeProperty = TextBlock.FontSizeProperty.AddOwner(
|
||||
typeof(OutlinedText), new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).glyphRun = null) { AffectsMeasure = true });
|
||||
typeof(OutlinedText),
|
||||
new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).text = null) { AffectsMeasure = true });
|
||||
|
||||
public static readonly DependencyProperty FontFamilyProperty = TextBlock.FontFamilyProperty.AddOwner(
|
||||
typeof(OutlinedText), new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).glyphRun = null) { AffectsMeasure = true });
|
||||
typeof(OutlinedText),
|
||||
new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).text = null) { AffectsMeasure = true });
|
||||
|
||||
public static readonly DependencyProperty FontStyleProperty = TextBlock.FontStyleProperty.AddOwner(
|
||||
typeof(OutlinedText), new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).glyphRun = null) { AffectsMeasure = true });
|
||||
typeof(OutlinedText),
|
||||
new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).text = null) { AffectsMeasure = true });
|
||||
|
||||
public static readonly DependencyProperty FontWeightProperty = TextBlock.FontWeightProperty.AddOwner(
|
||||
typeof(OutlinedText), new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).glyphRun = null) { AffectsMeasure = true });
|
||||
typeof(OutlinedText),
|
||||
new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).text = null) { AffectsMeasure = true });
|
||||
|
||||
public static readonly DependencyProperty FontStretchProperty = TextBlock.FontStretchProperty.AddOwner(
|
||||
typeof(OutlinedText), new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).glyphRun = null) { AffectsMeasure = true });
|
||||
typeof(OutlinedText),
|
||||
new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).text = null) { AffectsMeasure = true });
|
||||
|
||||
public static readonly DependencyProperty ForegroundProperty = TextBlock.ForegroundProperty.AddOwner(
|
||||
typeof(OutlinedText), new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).glyphRun = null) { AffectsMeasure = true });
|
||||
typeof(OutlinedText),
|
||||
new FrameworkPropertyMetadata((o, e) => ((OutlinedText)o).text = null) { AffectsMeasure = true });
|
||||
|
||||
public static readonly DependencyProperty BackgroundProperty = TextBlock.BackgroundProperty.AddOwner(
|
||||
typeof(OutlinedText), new FrameworkPropertyMetadata(Brushes.White, (o, e) => ((OutlinedText)o).glyphRun = null) { AffectsMeasure = true });
|
||||
typeof(OutlinedText),
|
||||
new FrameworkPropertyMetadata(Brushes.White, (o, e) => ((OutlinedText)o).text = null) { AffectsMeasure = true });
|
||||
|
||||
public static readonly DependencyProperty OutlineThicknessProperty = DependencyProperty.Register(
|
||||
"OutlineThickness", typeof(double), typeof(OutlinedText),
|
||||
new FrameworkPropertyMetadata(1d, FrameworkPropertyMetadataOptions.AffectsMeasure, (o, e) => ((OutlinedText)o).glyphRun = null));
|
||||
nameof(OutlineThickness), typeof(double), typeof(OutlinedText),
|
||||
new FrameworkPropertyMetadata(1d, FrameworkPropertyMetadataOptions.AffectsMeasure, (o, e) => ((OutlinedText)o).text = null));
|
||||
|
||||
public OutlinedText()
|
||||
{
|
||||
IsHitTestVisible = false;
|
||||
}
|
||||
|
||||
public string Text
|
||||
{
|
||||
|
|
@ -93,23 +107,23 @@ namespace SampleApplication
|
|||
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
return CheckGlyphRun() ? outline.Bounds.Size : new Size();
|
||||
return ValidateText() ? outline.Bounds.Size : new Size();
|
||||
}
|
||||
|
||||
protected override void OnRender(DrawingContext drawingContext)
|
||||
{
|
||||
if (CheckGlyphRun())
|
||||
if (ValidateText())
|
||||
{
|
||||
var location = outline.Bounds.Location;
|
||||
drawingContext.PushTransform(new TranslateTransform(-location.X, -location.Y));
|
||||
drawingContext.DrawGeometry(Background, null, outline);
|
||||
drawingContext.DrawGlyphRun(Foreground, glyphRun);
|
||||
drawingContext.DrawText(text, new Point());
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckGlyphRun()
|
||||
private bool ValidateText()
|
||||
{
|
||||
if (glyphRun == null)
|
||||
if (text == null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(Text))
|
||||
{
|
||||
|
|
@ -123,19 +137,22 @@ namespace SampleApplication
|
|||
return false;
|
||||
}
|
||||
|
||||
var glyphIndices = new ushort[Text.Length];
|
||||
var advanceWidths = new double[Text.Length];
|
||||
text = new FormattedText(Text,
|
||||
CultureInfo.InvariantCulture,
|
||||
FlowDirection.LeftToRight,
|
||||
typeface,
|
||||
FontSize,
|
||||
Foreground,
|
||||
VisualTreeHelper.GetDpi(this).PixelsPerDip);
|
||||
|
||||
for (int i = 0; i < Text.Length; i++)
|
||||
{
|
||||
var glyphIndex = glyphTypeface.CharacterToGlyphMap[Text[i]];
|
||||
glyphIndices[i] = glyphIndex;
|
||||
advanceWidths[i] = glyphTypeface.AdvanceWidths[glyphIndex] * FontSize;
|
||||
}
|
||||
|
||||
glyphRun = new GlyphRun(glyphTypeface, 0, false, FontSize, 1f, glyphIndices, new Point(), advanceWidths, null, null, null, null, null, null);
|
||||
|
||||
outline = glyphRun.BuildGeometry().GetWidenedPathGeometry(new Pen(null, OutlineThickness * 2d));
|
||||
outline = text.BuildGeometry(new Point()).GetWidenedPathGeometry(
|
||||
new Pen
|
||||
{
|
||||
Thickness = OutlineThickness * 2d,
|
||||
LineJoin = PenLineJoin.Round,
|
||||
StartLineCap = PenLineCap.Round,
|
||||
EndLineCap = PenLineCap.Round
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -16,12 +16,18 @@
|
|||
<Compile Include="..\Shared\*.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="..\Shared\MapLayers.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\MapControl\WPF\MapControl.WPF.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Resource Include="..\Shared\10_535_330.jpg" Link="10_535_330.jpg" />
|
||||
<Content Include="..\Shared\10_535_330.jpg" Link="10_535_330.jpg">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)'=='net48'">
|
||||
|
|
@ -29,4 +35,9 @@
|
|||
<Reference Include="System.Runtime.Caching" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="App.config">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Loading…
Add table
Add a link
Reference in a new issue