Hi,
I'm trying to adapt the sample http://help.infragistics.com/Help/NetAdvantage/WPF/2012.2/CLR4.0/html/xamWebMap_Add_Image_Using_Map_Elements.html in my project.
The thing is, I want to create layers and associate Value Template dynamically to it for each map element of another layer containing my spatial datas.
My code:
XAML:
<ig:XamMap x:Name="xamMap" Loaded="XamMap_Loaded" ElementClick="XamMapElementClick" MouseRightButtonDown="xamMap_MouseRightButtonDown" IsZoomable="False" IsPannable="False" Background="Transparent"> <ig:XamMap.Layers> <ig:MapLayer x:Name="UTElayer" FillMode="RandomInterpolate" VisibleFromScale="0"> <ig:MapLayer.Reader> <ig:SqlShapeReader x:Name="UTEreader" DataMapping="Data=Coord_UTE;Name=Code_UTE;ToolTip=Nom_UTE"> </ig:SqlShapeReader> </ig:MapLayer.Reader> </ig:MapLayer> </ig:XamMap.Layers> </ig:XamMap>
XAML.CS:
XamMap_Loaded
foreach (MapElement mapElement in xamMap.Layers["UTElayer"].Elements){ // Change the mapElement origin point from a list of coordinates int indexOfCode = lookForIndex(mapElement.Name.ToString(), "UTE","centroids"); Point pt = strToPoint(MapDataCentroids[indexOfCode]["Coord_Zone"]); mapElement.SymbolOrigin = xamMap.MapProjection.ProjectToMap(pt); // Create a layer for each mapElement containing a Value Template different for each mapElement SetDataTemplateOnLayer("UTE", mapElement); // Setting the SymbolElement to positionning the Value Template on each mapElement SetSymbolElementOnMapElement(mapElement);}
foreach (MapElement mapElement in xamMap.Layers["UTElayer"].Elements){ // Change the mapElement origin point from a list of coordinates int indexOfCode = lookForIndex(mapElement.Name.ToString(), "UTE","centroids"); Point pt = strToPoint(MapDataCentroids[indexOfCode]["Coord_Zone"]); mapElement.SymbolOrigin = xamMap.MapProjection.ProjectToMap(pt);
// Create a layer for each mapElement containing a Value Template different for each mapElement SetDataTemplateOnLayer("UTE", mapElement);
// Setting the SymbolElement to positionning the Value Template on each mapElement SetSymbolElementOnMapElement(mapElement);}
SetDataTemplateOnLayer
private void SetDataTemplateOnLayer(string layer, MapElement elementCourant){ MapLayer newLayer = new MapLayer(); newLayer.Name = elementCourant.Name; DataTemplate dtTest = new DataTemplate(); FrameworkElementFactory txtElement = new FrameworkElementFactory(typeof(TextBlock)); txtElement.SetValue(TextBlock.TextProperty, "TEXTBLOCK DE TEST"); dtTest.VisualTree = txtElement; newLayer.ValueTemplate = dtTest; xamMap.Layers.Add(newLayer); }
private void SetDataTemplateOnLayer(string layer, MapElement elementCourant){ MapLayer newLayer = new MapLayer(); newLayer.Name = elementCourant.Name; DataTemplate dtTest = new DataTemplate(); FrameworkElementFactory txtElement = new FrameworkElementFactory(typeof(TextBlock)); txtElement.SetValue(TextBlock.TextProperty, "TEXTBLOCK DE TEST"); dtTest.VisualTree = txtElement; newLayer.ValueTemplate = dtTest; xamMap.Layers.Add(newLayer);
}
SetSymbolElementOnMapElement
private void SetSymbolElementOnMapElement(MapElement elementCourant){ SymbolElement symbElement = new SymbolElement() { SymbolOrigin = elementCourant.SymbolOrigin, Caption = "SymbolElement: "+elementCourant.Name, SymbolType = MapSymbolType.None, SymbolSize = 90 }; // Assign arbitrary value so that Value Template can be used symbElement.Value = 1; xamMap.Layers[elementCourant.Name].Elements.Add(symbElement); // Make enough space in layer for the added shape Rect worldRect = xamMap.Layers[elementCourant.Name].WorldRect; worldRect.Union(symbElement.WorldRect); xamMap.Layers[elementCourant.Name].WorldRect = worldRect; }
private void SetSymbolElementOnMapElement(MapElement elementCourant){ SymbolElement symbElement = new SymbolElement() { SymbolOrigin = elementCourant.SymbolOrigin, Caption = "SymbolElement: "+elementCourant.Name, SymbolType = MapSymbolType.None, SymbolSize = 90 }; // Assign arbitrary value so that Value Template can be used symbElement.Value = 1; xamMap.Layers[elementCourant.Name].Elements.Add(symbElement); // Make enough space in layer for the added shape Rect worldRect = xamMap.Layers[elementCourant.Name].WorldRect; worldRect.Union(symbElement.WorldRect); xamMap.Layers[elementCourant.Name].WorldRect = worldRect;
When I run the program I get :
Only the SymbolElement Caption is displayed and my DataValue seems to disappear of the layer.
My question is simple: what's wrong with my code ? I can't figure out atm.
Hoping my demand is clear,Many thanks for your answers.
Hi dupond,
I'm looking into this issue for you. I believe I've reproduced it on my end and it seems to be caused by an InvalidOperationException with the DataTemplate. I haven't figured out why yet but in your output window do you see a few entries for a first chance exception of type 'InvalidOperationException'?
Hi Rob,Thanks for your answer. I looked in my execution what methods causes the 'InvalidOperationException' and I found out three of them in the VisualTree.Type property of my DataTemplate:- get_DeclaringMethod- get_GenericParameterAttributes- get_GenericParameterPositionThese three methods throw the 'InvalidOperationException' with a message error: "Method may only be called on a Type for which Type.IsGenericParameter is true"I don't know what does it means in my case.
Hi,I finally solved my issue using XamlReader instead of FrameworkElementFactory.Here's the code if it can help:
private void SetDataTemplateOnLayer(string layer, MapElement elementCourant){ MapLayer newLayer = new MapLayer(); newLayer.Name = elementCourant.Name; StringReader sr = new StringReader(@"<DataTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""> <TextBlock Text=""TEXTBLOCK TEST"" /> </DataTemplate>"); newLayer.ValueTemplate = (DataTemplate) XamlReader.Load(XmlReader.Create(sr)); xamMap.Layers.Add(newLayer); }
private void SetDataTemplateOnLayer(string layer, MapElement elementCourant){ MapLayer newLayer = new MapLayer(); newLayer.Name = elementCourant.Name;
StringReader sr = new StringReader(@"<DataTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""> <TextBlock Text=""TEXTBLOCK TEST"" /> </DataTemplate>");
newLayer.ValueTemplate = (DataTemplate) XamlReader.Load(XmlReader.Create(sr)); xamMap.Layers.Add(newLayer);
I'm glad you were able to resolve your issue. Let me know if you have any further questions on this.