Graphic Click InfoWindow

1100
7
04-21-2011 07:50 AM
ThomasSchultz
New Contributor III
I am trying to add an event to my application so that when the user clicks on a graphic in a graphics layer, an InfoWindow or something similar opens.  Each graphic has about 3 attributes that I want to display in the InfoWindow, one of which is a URL to an image that I would like to use as the source for an image inside of the InfoWindow.  I was able to do this in Flex by putting a graphic click handler inside of a for each statement and then , but have so far been unable to translate this to Silverlight.  Here is the Flex code for each statement and event handler function:

for each (myGraphicGraphical in featureSet.features)
{   
var thumbURL:String = myGraphicGraphical.attributes.ThumbURL;
var fullURL:String = myGraphicGraphical.attributes.FullURL;
var imageGraphicalSym:PictureMarkerSymbol = new PictureMarkerSymbol(thumbURL,20,20,0,0,0);
myGraphicGraphical.symbol= imageGraphicalSym;
myGraphicGraphical.addEventListener(MouseEvent.CLICK,graphicClick);
graphicsGraphicalLayer.add(myGraphicGraphical);
}

private function graphicClick(event:MouseEvent):void
{
infoWindowBox.visible = true;
infoWindowBox.removeElement(infoWindowBoxImage);
label1.text = event.currentTarget.attributes.CaptureDate;
label2.text = event.currentTarget.attributes.Category;
label3.text = event.currentTarget.attributes.SourceID;
label4.text = event.currentTarget.attributes.Location;
label5.text = event.currentTarget.attributes.Purpose;   
infoWindowImage = event.currentTarget.attributes.ThumbURL;
infoWindowBoxImage.source = infoWindowImage;
infoWindowBox.addElement(infoWindowBoxImage);
map.infoWindowContent = infoWindowBox;
map.infoWindow.show(map.toMapFromStage(event.stageX, event.stageY));
fullURL = event.currentTarget.attributes.FullURL;
infoWindowBoxImage.addEventListener(MouseEvent.CLICK,showFullImage);
}

I've figured out how to add a graphic click event inside of my Silverlight for each statement and event handler function, but I'm not sure how to pass something similar to "event.currentTarget" to the handler function so it knows what graphic attributes to display.
0 Kudos
7 Replies
JenniferNery
Esri Regular Contributor
0 Kudos
ThomasSchultz
New Contributor III
I did look at the InfoWindow SDK sample, but couldn't get that method to work.  I'm not sure if it's because I'm trying to implement this as an add-in to the beta viewer, but I didn't have any luck adding it as a map click event as is shown in the sample.  Instead, I did finally get it to work yesterday by adding a graphicslayer click event, as I did in my Flex application.  I added the click event after my foreach graphic statement with:   photoGraphicsLayer.MouseLeftButtonDown += new GraphicsLayer.MouseButtonEventHandler(GraphicClick);.  Then I get all of my attribute values in my click handler function with:  void GraphicClick(object sender, GraphicMouseButtonEventArgs e)
{
Graphic gra = e.Graphic;
}.

Now I just need to show these attributes in an infowindow.  This was very easy in Flex with the infoWindowBox.addElement and map.infoWindow.show methods.  If you have any pointers on doing this, I'd really appreciate them.
0 Kudos
ThomasSchultz
New Contributor III
Okay,  I got the InfoWindow to open with a content template on graphic click.  The last thing I need to do is get some text blocks text bound to attribute values.  Here is my click function:

void GraphicClick(object sender, GraphicMouseButtonEventArgs e)
        {
            Graphic gra = e.Graphic;
            string graCaptureDate = gra.Attributes["CaptureDate"].ToString();
            string graCategory = gra.Attributes["Category"].ToString();
            string graSourceID = gra.Attributes["SourceID"].ToString();
            string graLocation = gra.Attributes["Location"].ToString();
            string graPurpose = gra.Attributes["Purpose"].ToString();
            string graThumbURL = gra.Attributes["ThumbURL"].ToString();
            string graFullURL = gra.Attributes["FullURL"].ToString();
            Uri graThumbUri = new Uri(graThumbURL, UriKind.Absolute);
            Uri graFullUri = new Uri(graFullURL, UriKind.Absolute);
           
            MapPoint myMapPoint = new MapPoint();
            myMapPoint = gra.Geometry as MapPoint;

            InfoWindow myInfoWindow = new InfoWindow();           
            myInfoWindow.Anchor = myMapPoint;
            myInfoWindow.IsOpen = true;
            myInfoWindow.Map = MapApplication.Current.Map;
            myInfoWindow.ContentTemplate = LayoutRoot.Resources["InfoWindowTemplate"] as System.Windows.DataTemplate;

            LayoutRoot.Children.Add(myInfoWindow);
        } 

And here is my data template:

<DataTemplate x:Key="InfoWindowTemplate" x:Name="InfoWindowTemplate">
                <StackPanel x:Name="InfoStack" Orientation="Vertical" Margin="10,10,10,10" Background="Transparent">
                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Background="Transparent">
                        <TextBlock Text="Capture Date: " FontWeight="Bold"/>
                        <TextBlock x:Uid="textCaptureDate" x:Name="textCaptureDate"/>
                    </StackPanel>
                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Background="Transparent">
                        <TextBlock Text="Category: " FontWeight="Bold"/>
                        <TextBlock x:Name="textCategory"/>
                    </StackPanel>
                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Background="Transparent">
                        <TextBlock Text="Source ID: " FontWeight="Bold"/>
                        <TextBlock x:Name="textSourceID"/>
                    </StackPanel>
                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Background="Transparent">
                        <TextBlock Text="Location: " FontWeight="Bold"/>
                        <TextBlock x:Name="textLocation"/>
                    </StackPanel>
                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" Background="Transparent">
                        <TextBlock Text="Purpose: " FontWeight="Bold"/>
                        <TextBlock x:Name="textPurpose"/>
                    </StackPanel>
                </StackPanel>
            </DataTemplate>

How can I bind the text blocks to the attributes?  Now that the blocks are inside of the data template I can no longer access them directly in the code behind.  I also tried to do it as in the sample, but I got runtime errors.
0 Kudos
JenniferNery
Esri Regular Contributor
You missed to set InfoWindow.Content = e.Graphic.Attributes.

This sets the DataContext of your DataTemplate, which will allow you to bind to the field name.
           <DataTemplate x:Key="MyFeatureLayerInfoWindowTemplate">
                <TextBlock Text="{Binding [STATE_NAME]}" Foreground="Black" FontSize="12" />
            </DataTemplate>
0 Kudos
ThomasSchultz
New Contributor III
Thanks Jennifer!  That missing property setting was the problem.  The InfoWindows are working beautifully now.
0 Kudos
AnastasiaAourik
New Contributor II
I'd like to put my datatemplate in a separate xaml file, not in the <Grid.Resources>
This is because I will have many many data templates and they will be complex and really long.
I'd like to have them in a separate for better code readiblity.

I have 25 layers, each that may be clicked and have it's own unique infowindow template,
and its own set of attributes that we have in the g.Attributes  (g is the Graphic) that was clicked in
the Map_MouseClick event  using  IEnumerable<Graphic> selected = fl.FindGraphicsInHostCoordinates(transformedScreenPnt);

Can you assist?
0 Kudos
DominiqueBroux
Esri Frequent Contributor
0 Kudos