I'm wanting to design a control that has XamMap with the DataSource bounded to IEnumerable<object>, the object has many properties and one a Microsoft.SqlServer.Types.SqlGeometry type property used to generate a Microsoft Report.
So I would like to map these geometries and caption on another property of the object, allowing the user to select a polygon -> raising an event (good if the event args would supply the object from the IEnumerable) that presents the other object properties in another control (Datagrid?)
Does anyone have something like this to share or is XamMap not upto the task. Would have thought a example/sample would have been available at infragistics?
Hello and thank you for posting.
I have been looking into your post and I am not completely sure I understand correctly your scenario. Do you want the user to be able to select multiple items that are rendered on a map layer? Would it be possible to share an image that shows more details on the matter? Thank you in advance.
Solved most of what I was asking about, have attach image of resultant control
The main part I'm missing now is a better way of retrieving the underlying object from XamMap Control
Here's the basic code for anyone else, or for you to make better sense of what I am meaning
public partial class XamMapControl : UserControl{ private MapElement _element; private Rect _worldRect = default(Rect); private Color[] _brightcolours;
public XamMapControl() { InitializeComponent(); }
public event EventHandler<SelectionEventArgs> SelectionCanged; public static readonly DependencyProperty DataSourceProperty = DependencyProperty.Register("DataSource", typeof(IEnumerable), typeof(XamMapControl), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
[Bindable(true)] public IEnumerable DataSource { get { return (IEnumerable)this.GetValue(DataSourceProperty); } set { this.SetValue(DataSourceProperty, value); this.MapLayer.DataSource = value; ((SqlShapeReader)this.MapLayer.Reader).DataSource = value; if (DataMapping != null) MapLayer.ImportAsync(); } }
public static readonly DependencyProperty DataMappingProperty = DependencyProperty.Register("DataMapping", typeof(DataMapping), typeof(XamMapControl), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
[Bindable(true)] public DataMapping DataMapping { get { return (DataMapping)this.GetValue(DataMappingProperty); } set { this.SetValue(DataMappingProperty, value); this.MapLayer.DataMapping = value; this.MapLayer.Reader.DataMapping = value; if (DataSource != null) MapLayer.ImportAsync(); } }
public static readonly DependencyProperty SelectedObjectProperty = DependencyProperty.Register("SelectedObject", typeof(object), typeof(XamMapControl), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
[Bindable(true)] public object SelectedObject { get { return this.GetValue(SelectedObjectProperty); } set { this.SetValue(SelectedObjectProperty, value); } }
private void XamMap_Loaded(object sender, RoutedEventArgs e) { var mapping = new DataMapping(); mapping.Add(new DataMappingPair("Data", "SQLGeometry")); mapping.Add(new DataMappingPair("Caption", "Name")); mapping.Add(new DataMappingPair("Name", "Name")); mapping.Add(new DataMappingPair("Value", "FID"));
this.DataMapping = mapping;
}
private void MapLayer_Imported_1(object sender, MapLayerImportEventArgs e) { _brightcolours = PaddockGRASP.Mapping.Methods.ColourScheme.GetPreCodedColor(MapLayer.Elements.Count);
// Check each Map Element int i = 0; var colors = PaddockGRASP.Mapping.Methods.ColourScheme.GetGradientColorRamp(MapLayer.Elements.Count, System.Drawing.Color.LightGray, Color.DarkGray); foreach (MapElement element in MapLayer.Elements) { element.Fill = new SolidColorBrush(System.Windows.Media.Color.FromArgb(125, _brightcolours[i].R, _brightcolours[i].G, _brightcolours[i++].B)); } }
private void XamMap_OnElementClick(object sender, MapElementClickEventArgs e) { if (_worldRect == default(Rect)) _worldRect = XamMap.WindowRect;
XamMap.WindowRect = e.Element.WorldRect; var enumer = DataSource.AsQueryable().Where("FID=" + e.Element.Value).GetEnumerator(); enumer.MoveNext(); SelectedObject = enumer.Current;
if (SelectionCanged != null) SelectionCanged(this, new SelectionEventArgs() {Selection = SelectedObject }); _element = e.Element; }
private void XamMap_OnMouseRightButtonDown(object sender, MouseButtonEventArgs e) { if (_worldRect != default(Rect)) { XamMap.WindowRect = _worldRect; //XamMap.InvalidateVisual(); } }}
public class SelectionEventArgs : EventArgs{ public object Selection { get; set; }}
<UserControl x:Class="Views.XamMapControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:ig="http://schemas.infragistics.com/xaml" xmlns:providers="clr-namespace:Views" x:Name="MapUserControl" mc:Ignorable="d" d:DesignHeight="800" d:DesignWidth="800" Loaded="XamMap_Loaded"> <UserControl.Resources> </UserControl.Resources> <Grid> <ig:XamMap x:Name="XamMap" Background="WhiteSmoke" SelectionChanged="XamMap_OnSelectionChanged" ElementClick="XamMap_OnElementClick" MouseRightButtonDown="XamMap_OnMouseRightButtonDown"> <ig:XamMap.Layers> <ig:MapLayer x:Name="MapLayer" FillMode="None" Imported="MapLayer_Imported_1"> <ig:MapLayer.Background> <RadialGradientBrush> <GradientStop Color="Linen" Offset="1"/> <GradientStop Color="WhiteSmoke"/> </RadialGradientBrush> </ig:MapLayer.Background> <ig:MapLayer.Reader> <ig:SqlShapeReader > <ig:SqlShapeReader.CoordinateSystem> <ig:CoordinateSystem FalseEasting="0" FalseNorthing="0" UnitType="M"> <ig:CoordinateSystem.Projection> <ig:Mercator CentralMeridian="0" EllipsoidType="WGS84" /> </ig:CoordinateSystem.Projection> </ig:CoordinateSystem></ig:SqlShapeReader.CoordinateSystem> </ig:SqlShapeReader> </ig:MapLayer.Reader> </ig:MapLayer> </ig:XamMap.Layers> </ig:XamMap> </Grid></UserControl>
public partial class SelectableMapControl : UserControl{ private object _selectedObject; private IEnumerable _dataSource;
public SelectableMapControl() { InitializeComponent(); } public object SelectedObject { get { return _selectedObject; } set { _selectedObject = value; SelectPropertyGrid.SelectedObject = _selectedObject; } }
public IEnumerable DataSource { get { return _dataSource; } set { _dataSource = value; XamMapUserControl.DataSource = _dataSource;
} }
private void XamMapControl_OnSelectionCanged(object sender, SelectionEventArgs e) { }}
<UserControl x:Class="Views.SelectableMapControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:views="clr-namespace:Views" xmlns:propertyGrid="http://schemas.denisvuyka.wordpress.com/wpfpropertygrid" x:Name="SelectUserControl" mc:Ignorable="d" d:DesignHeight="600" d:DesignWidth="600"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <views:XamMapControl Grid.Column="0" x:Name="XamMapUserControl" SelectionCanged="XamMapControl_OnSelectionCanged" SelectedObject="{Binding ElementName=SelectUserControl, Path=SelectedObject}"/>
<propertyGrid:PropertyGrid Grid.Column="1" x:Name="SelectPropertyGrid" > <!--ShowReadOnlyProperties="True" ShowAttachedProperties="True"--> <propertyGrid:PropertyGrid.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <propertyGrid:KaxamlTheme/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </propertyGrid:PropertyGrid.Resources> </propertyGrid:PropertyGrid> </Grid></UserControl>
Thank you for the feedback and the provided code. It seems that I could not suggest you a better solution at the moment.
This approach could be helpful for other community members as well so thank you again for sharing.