WPF开发Arcgis的时候如果在地图上添加点图标是很容易实现的,自定义一下Symbol的模板即可实现。但是如果模板中标题文字不固定的时候,点图标没法做偏移(点图标在地图上锚定的时候是以左上角的点位锚定点,如果图标的下部中点和锚点重合就没有这个问题),这样会造成放大和缩小地图的时候点图标乱动的效果。线面介绍一种做偏移的方法,基本思路是使用3个俯角属性绑定模板中控件的实际宽高及模板数据源Symbol,然后处理偏移,OffsetX取实际宽的一半,OffsetY取实际高度,代码如下:
首先自定义一个点图标(使用现有的PictureMarkerSymbol也行,但是需要附加属性控制字体颜色背景之类的)
///
/// 模块编号:控件库
/// 作用:带有图片及标题的地图点标识
/// 作者:丁纪名
/// 编写日期:2018-01-22
///
public class TitlePictureMarkerSymbol : MarkerSymbol
{
///
/// 图片数据源
///
public ImageSource Source
{
get { return (ImageSource)GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); }
}
// Using a DependencyProperty as the backing store for Source. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SourceProperty =
DependencyProperty.Register("Source", typeof(ImageSource), typeof(TitlePictureMarkerSymbol), new PropertyMetadata(null));
/// <summary>
/// 标题
/// </summary>
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
// Using a DependencyProperty as the backing store for Title. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(string), typeof(TitlePictureMarkerSymbol), new PropertyMetadata(null));
/// <summary>
/// 标题字体大小
/// </summary>
public double FontSize
{
get { return (double)GetValue(FontSizeProperty); }
set { SetValue(FontSizeProperty, value); }
}
// Using a DependencyProperty as the backing store for FontSize. This enables animation, styling, binding, etc...
public static readonly DependencyProperty FontSizeProperty = TextElement.FontSizeProperty.AddOwner(
typeof(TitlePictureMarkerSymbol),
new FrameworkPropertyMetadata(SystemFonts.MessageFontSize,
FrameworkPropertyMetadataOptions.Inherits));
/// <summary>
/// 标题前景色
/// </summary>
public Brush Foreground
{
get { return (Brush)GetValue(ForegroundProperty); }
set { SetValue(ForegroundProperty, value); }
}
// Using a DependencyProperty as the backing store for Foreground. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ForegroundProperty = TextElement.ForegroundProperty.AddOwner(
typeof(TitlePictureMarkerSymbol),
new FrameworkPropertyMetadata(SystemColors.ControlTextBrush,
FrameworkPropertyMetadataOptions.Inherits));
/// <summary>
/// 文本背景色
/// </summary>
public Brush Background
{
get { return (Brush)GetValue(BackgroundProperty); }
set { SetValue(BackgroundProperty, value); }
}
// Using a DependencyProperty as the backing store for Background. This enables animation, styling, binding, etc...
public static readonly DependencyProperty BackgroundProperty = Panel.BackgroundProperty.AddOwner(typeof(TitlePictureMarkerSymbol),
new FrameworkPropertyMetadata(
Panel.BackgroundProperty.DefaultMetadata.DefaultValue,
FrameworkPropertyMetadataOptions.None));
public static double GetWidth(DependencyObject obj)
{
return (double)obj.GetValue(WidthProperty);
}
public static void SetWidth(DependencyObject obj, double value)
{
obj.SetValue(WidthProperty, value);
}
// Using a DependencyProperty as the backing store for Width1. This enables animation, styling, binding, etc...
public static readonly DependencyProperty WidthProperty =
DependencyProperty.RegisterAttached("Width", typeof(double), typeof(TitlePictureMarkerSymbol), new FrameworkPropertyMetadata(default(double), new PropertyChangedCallback(OnWidthChanged)));
private static void OnWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FrameworkElement element = d as FrameworkElement;
if (element != null)
{
TitlePictureMarkerSymbol symbol = TitlePictureMarkerSymbol.GetSymbol(element) as TitlePictureMarkerSymbol;
if (symbol != null)
{
symbol.OffsetX = element.ActualWidth / 2;
}
}
}
public static double GetHeight(DependencyObject obj)
{
return (double)obj.GetValue(HeightProperty);
}
public static void SetHeight(DependencyObject obj, double value)
{
obj.SetValue(HeightProperty, value);
}
// Using a DependencyProperty as the backing store for Height1. This enables animation, styling, binding, etc...
public static readonly DependencyProperty HeightProperty =
DependencyProperty.RegisterAttached("Height", typeof(double), typeof(TitlePictureMarkerSymbol), new FrameworkPropertyMetadata(default(double), new PropertyChangedCallback(OnHeightChanged)));
private static void OnHeightChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FrameworkElement element = d as FrameworkElement;
if (element != null)
{
TitlePictureMarkerSymbol symbol = TitlePictureMarkerSymbol.GetSymbol(element) as TitlePictureMarkerSymbol;
if (symbol != null)
{
symbol.OffsetY = element.ActualHeight;
}
}
}
public static object GetSymbol(DependencyObject obj)
{
return (object)obj.GetValue(SymbolProperty);
}
public static void SetSymbol(DependencyObject obj, object value)
{
obj.SetValue(SymbolProperty, value);
}
// Using a DependencyProperty as the backing store for Symbol. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SymbolProperty =
DependencyProperty.RegisterAttached("Symbol", typeof(object), typeof(TitlePictureMarkerSymbol), new PropertyMetadata(null));
}
定义模板:
使用方式:
var symbol = new TitlePictureMarkerSymbol
{
Source = img,
Background = Brushes.DimGray,
FontSize = 12,
Foreground = Brushes.White
};
symbol.ControlTemplate = SymbolResource.Resource[“TitlePictureMarkerSymbolStyle”] as ControlTemplate;
如此即可实现不固定宽度的图片文本点图标了。