Chitra,The code for my custom FlareClusterer class is below, as well a snippet of the code from my Map_MouseLeftButtonDown event handler. To provide a bit of background on what I am doing in my project, I have a world map to which I am adding graphics that represent each member of the organization for which I work. My goal was to be able to click on any of the "dots" on the map and from there display either a list of all the people at that location or if a single "dot" was clicked, then display the personal information for the person clicked.Currently, I do not have a need to do any further manipulation of the FlareClusterer, so my CustomFlareClusterer is very simple, and is only used to add my "ElementIndex" attribute to each Graphic object.CustomFlareClusterer.cs
using ESRI.ArcGIS.Client;
using ESRI.ArcGIS.Client.Geometry;
namespace MySilverlightProject.Controls
{
public class CustomFlareClusterer : FlareClusterer
{
protected override Graphic OnCreateGraphic(GraphicCollection cluster, MapPoint point, int maxClusterCount)
{
int elementIndex = 0;
// Loop through the Graphics in the cluster, and add an ElementIndex attribute to each item
foreach (Graphic g in cluster)
{
// First, check to see if the Graphic object already contains the ElementIndex attribute, and reset it if necessary.
// This is necessary to handle cases where the Graphic object was part of a large collection of Graphics prior to
// the user zooming in to get to the Flare Clusterer object on the map.
if (g.Attributes.ContainsKey("ElementIndex"))
g.Attributes["ElementIndex"] = elementIndex;
else
g.Attributes.Add("ElementIndex", elementIndex);
elementIndex++;
}
// Now pass our modified GraphicCollection object, "cluster," into the GraphicClusterer OnCreateGraphic method
return base.OnCreateGraphic(cluster, point, maxClusterCount);
}
}
}
To handle the click event of any Graphics on the map, I have wrapped everything into the Map_MouseLeftButtonDown event handler. This allows me to avoid having to handle Graphics in a Clusterer separately from stand-alone Graphics. I've left a lot of my code out of the snippet below, but you should be able to discern how I am using the ElementIndex attribute on each Graphic object to figure out which element of a flare was clicked.Map_MouseLeftButtonDown event handler
private void Map_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
// Attempt to case the clicked object to an Ellipse object
Ellipse ellipse = e.OriginalSource as Ellipse;
// Get a reference to the map's GraphicsLayer
GraphicsLayer graphicsLayer = Map.Layers["DynamicGraphicsLayer"] as GraphicsLayer;
GeneralTransform generalTransform = Map.TransformToVisual(Application.Current.RootVisual);
System.Windows.Point transformScreenPnt = generalTransform.Transform(e.GetPosition(this.Map));
var graphics = graphicsLayer.FindGraphicsInHostCoordinates(transformScreenPnt);
foreach (Graphic g in graphics)
{
// If the Graphic object clicked by the user is not part of a cluster...
if (graphics.Count<Graphic>() == 1)
{
// Add processing code here. What I do is navigate to another page, and pass in the associated Id Attribute of the
// Graphic object that was clicked.
// Exit
break;
}
// Check to see if the object clicked by the user was actually an Ellipse object. The object will be an ellipse if
// the user clicked on one of the "flares," but that may or may not be the case if they clicked on the center Graphic
// of a cluster, or if they click on a cluster that contains too many objects to be a FlareClusterer.
if (ellipse != null)
{
if (ellipse.Name.ToLower() == "mainsymbol")
{
// The Ellipse that represents the center of a cluster was clicked, so what I do here is create a list of
// the "Ids" for each Graphic in cluster. The Id is pulled from the Attributes.
// Add processing code here. I display a panel on the side of the map with a list of people at the location clicked.
}
else if (ellipse.Name.ToLower().StartsWith("elm"))
{
// Each "flare" in a cluster is an Ellipse with a name that is "elm" + an index starting from the right-hand side
// and going around clockwise. The first "flare" will be named "elm0," the second "elm1," and so on. Using that
// information, we can match our ElementIndex up with the element clicked to figure out which "flare" within the
// cluster was clicked. All we need to do is prepend "elm" to our ElementIndex and compare it the name of the
// Ellipse that was clicked.
if ((g.Attributes.ContainsKey("ElementIndex")) && ("elm" + g.Attributes["ElementIndex"].ToString() == ellipse.Name))
{
// Add processing code here. What I do is navigate to another page, and pass in the associated Id Attribute of the
// Graphic object that was clicked.
// Exit, since we've found what we were looking for.
break;
}
}
else
{
// Add processing code here. I display a panel on the side of the map with a list of people at the location clicked.
}
}
else
{
// This should be used to handle the cases where the user clicked on a GraphicClusterer, but the actual click event
// was fired for a child of the Ellipse object, such as the text containing the number of items in the cluster.
// Add processing code here. I display a panel on the side of the map with a list of people at the location clicked.
}
}
}
Hope this helps.Cheers,Kyle