Hi
How can I add Symbol Elements to XamWebMap that have different gif images ?
Ah, I think I see what you mean.
Solution #1: You could do this by creating a distinct MapLayer for each SymbolElement. So, each time you would like to add a custom image, you could create a MapLayer, set its ValueTemplate, and add the SymbolElement. Here's an example:
In XAML:
<UserControl.Resources> <DataTemplate x:Name="dtPizza"> <Image Width="50" Height="50" Source="pizza.png" /> </DataTemplate> <!-- Insert additional custom DataTemplates here ... --> </UserControl.Resources>
Then in C#:
private void statesLayer_Loaded(object sender, RoutedEventArgs e) { string s = "dtPizza"; if (this.Resources.Contains(s)) { // Create Layer MapLayer layer = new MapLayer();
// Fetch ValueTemplate from Resources DataTemplate dt = this.Resources[s] as DataTemplate; layer.ValueTemplate = dt;
// Create Customized-Image Element Point origin = map1.MapProjection.ProjectToMap(new Point(0, 0)); SymbolElement element = new SymbolElement() { SymbolOrigin = origin, SymbolType = MapSymbolType.None, SymbolSize = 20 }; element.Value = 1; // Assign arbitrary value so that Value Template can be used
// add element to layer layer.Elements.Add(element);
// add layer to xamMap map1.Layers.Add(layer);
// make enough space in layer for shape Rect worldRect = layer.WorldRect; worldRect.Union(element.WorldRect); layer.WorldRect = worldRect; } }
Basically, we look for the resource called "dtPizza" and use it to place a pizza image on the map. You can define additional DataTemplates in UserControl.Resources so that you can place other images.
This example adds the image programmatically, but you could also do something equivalent using only XAML.
Solution #2: If you don't want to add so many MapLayers, you could also define a single MapLayer and set the ValueTemplate to a custom object. Then you would bind the MapElement Value to a field of your custom object, and the custom object would render an image that is different depending on the Value. This actually seems like more work to me, but it might be appropriate in some cases.
I hope this helps answer your question?
Another approach you can use is to create a value that you can bind against on each element that specifies the image url to use for that element.
You will notice that the Value, however, is a just a double, so its not immediately obvious how you can make a url accessible to the value template of an element.
However, you can use Attached Properties to set a url for each element that you want to display an image for, and bind to the attached property in your value template.
This sample uses a similar strategy (but is more complicated because it also implements a data tempalte selector pattern): https://ko.infragistics.com/community/forums/f/retired-products-and-controls/37528/ist-possible-to-add-user-controls-over-map/218358#218358
Let me know if you want some further elaboration here.
-Graham
Here's an example:The Xaml:
<igMap:XamWebMap x:Name="theMap"> <igMap:XamWebMap.Layers> <igMap:MapLayer x:Name="theLayer" IsAutoWorldRect="True" Imported="theLayer_Imported" > <igMap:MapLayer.Reader> <igMap:ShapeFileReader Uri="ShapeFiles\usa_st" DataMapping="Name=STATE_NAME" /> </igMap:MapLayer.Reader> <igMap:MapLayer.ValueTemplate> <DataTemplate> <Image Width="40" Height="40" xmlns:local="clr-namespace:SilverlightApplication77;assembly=SilverlightApplication77" Source="{Binding Path=(local:MapData.ValueData)}" /> </DataTemplate> </igMap:MapLayer.ValueTemplate> </igMap:MapLayer> </igMap:XamWebMap.Layers> </igMap:XamWebMap>
And the code behind:
public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); } private void theLayer_Imported( object sender, MapLayerImportEventArgs e) { if (e.Action == MapLayerImportAction.End) { foreach (MapElement ele in theMap.Layers[0].Elements) { if (ele.Name == "New York") { MapData.SetValueData( ele, new Uri("/Images/ny.png", UriKind.Relative)); } else if (ele.Name == "Pennsylvania") { MapData.SetValueData( ele, new Uri("/Images/pa.png", UriKind.Relative)); } } } } } public class MapData : DependencyObject { public static readonly DependencyProperty ValueDataProperty = DependencyProperty.RegisterAttached( "ValueData", typeof(object), typeof(MapData), new PropertyMetadata(null)); public static object GetValueData( DependencyObject target) { return target.GetValue(MapData.ValueDataProperty); } public static void SetValueData( DependencyObject target, object value) { target.SetValue(MapData.ValueDataProperty, value); } }