Select to view content in your preferred language

Inserting images into LayerTOC datagrid.

1584
12
12-06-2010 10:11 AM
JasonLevine
Deactivated User
Hello all,
   I'm using the "Dynamic Map Layers on/off" sample in the code sample gallery.  I'm trying to insert a new DataGridColumn in the data grid and embed an image that represents each layer's symbol.  This is what my code looks like in the LayerTOC.mxml:
    <mx:columns>
        <mx:DataGridColumn width="57"
                           headerText="Visibility"
                           itemRenderer="com.esri.ags.samples.LayerVizRenderer"/>
  <mx:DataGridColumn width="57"
         headerText="Symbol">
   <mx:itemRenderer>
    <fx:Component>
     <mx:HBox width="100%" horizontalAlign="center" verticalAlign="middle">
      <mx:Image id="legendSymbol2" source="assets/images/crosshair.png"/>
     </mx:HBox>
    </fx:Component>
   </mx:itemRenderer>
  </mx:DataGridColumn>
        <mx:DataGridColumn dataField="name" headerText="Layer Name" width="163"/>
    </mx:columns>


The problem that I'm having is that every layer shows my crosshair.png image (see attached image).

How do I code a separate image for each of the layers in my TOC?

An example of this can be seen in the map at the bottom of this page: http://crownpeak.vipnet.org/cmsportal3/

Thanks for your help,
Jason
Tags (2)
0 Kudos
12 Replies
RobertScheitlin__GISP
MVP Emeritus
Jason,

   You would have to do something like:
<mx:Image id="legendSymbol2" source="{data.imagepath}"/>

Where imagepath would be one of the fields/attributes of the data that is in the grid and would contain info like assets/images/crosshair.png
0 Kudos
JasonLevine
Deactivated User
Hi Robert,
   Are you saying that in my actual layers, I need to create a field called imagepath in arcMap and populate that field with the source of my image?

-Jason
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
Jason,

   No not exactly (that could work) but what I was thinking of involves working with the dataprovider of the grid and adding the new data of imagepath to it.
0 Kudos
JasonLevine
Deactivated User
Hi Robert,
   I had a feeling you might say that.  With my limited knowledge of datagrids, I've been trying to figure out how to do this.  It looks like a dataprovider isn't specified for the LayerTOC datagrid and the datagrid columns are defined inline.  Do you have an example of how to create a dataprovider for the grid and then add everything to it?

Thanks,
Jason
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
Jason,

    Try this:
<mx:columns>
        <mx:DataGridColumn width="57"
                           headerText="Visibility"
                           itemRenderer="com.esri.ags.samples.LayerVizRenderer"/>
  <mx:DataGridColumn width="57"
         headerText="Symbol" dataField="name" itemRenderer="com.esri.ags.samples.SymRenderer"/>
        <mx:DataGridColumn dataField="name" headerText="Layer Name" width="163"/>
    </mx:columns>

and create a new mxml component in the samples folder called "SymRenderer"
and paste this code into it.
<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" horizontalAlign="center"
    implements="mx.controls.listClasses.IDropInListItemRenderer">
    
    <mx:Script>
        <![CDATA[
            import com.esri.ags.layers.LayerInfo;
            import mx.controls.listClasses.BaseListData;
            
            [Bindable("dataChange")]
            private var _listData:BaseListData;
            
            [Bindable]
   private var SymPath:String = "";
            
            public function get listData():BaseListData
            {
                return _listData;
            }
            
            public function set listData(value:BaseListData):void
            {
                _listData = value;
                switch(listData.label)
    {
     case "EmergencySirens":
     {
      SymPath = "assets/i_fluries.png";
      break;
     }
     case "FireStations":
     {
      SymPath = "assets/i_fog.png";
      break;
     }
     case "TrafficCams":
     {
      SymPath = "assets/i_snow.png";
      break;
     }
     case "PoliceStations":
     {
      SymPath = "assets/i_hazy.png";
      break;
     }
     default:
     {
      SymPath = "";
      break;
     }
    }
            }
        ]]>
    </mx:Script>
    <mx:HBox width="100%" horizontalAlign="center" verticalAlign="middle">
  <mx:Image id="legendSymbol2" source="{SymPath}"/>
 </mx:HBox>
</mx:HBox>


and of course change the names of the labels of the layers from what I have to your (i.e. EmergencySirens to your layername) and the symPaths to match your images and paths.
0 Kudos
DasaPaddock
Esri Regular Contributor
LayerTOC extends DataGrid and set's its dataProvider in its setDataProvider() function. It's set to an Array of LayerInfo classes. You could extend LayerInfo to add another property to it.
0 Kudos
JasonLevine
Deactivated User
Hi Robert,
  Thanks, this worked great!

Dasa,
   I didn't notice that the datagrid sets its dataProvider in the actionscript.  How would I extend the layerInfos array to add the "source" property?

Thanks,
Jason
0 Kudos
JasonLevine
Deactivated User
Hi Robert,
     I've used your code to create a new itemRenderer for another datagridcolumn I've added to my LayerTOC datagrid.  In the itemClick function in my LayerTOC datagrid, I populate the variable "SelectedLayerName" and then pass it into the itemRenderer.  When I click the row, this SelectedLayerName variable will determine which switch/case the itemRenderer will use to set the sources for the images.  I want the selected row to display the image, while the other rows display no image (to show the user which layer is active for identifying).  I've put the following code together, but it doesn't seem to be working.  Can you see what I'm doing wrong?  Am I not allowed to nest switch statements in if/else statements?

Here's my itemClick function in my LayerTOC datagrid:
public static var SelectedLayerName:String = new String();
private function onItemClick(event:ListEvent):void
   {
    SelectedLayerName = this.selectedItem.name;
                        }


And here's my itemRenderer:
<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml" horizontalAlign="center"
   implements="mx.controls.listClasses.IDropInListItemRenderer">
 
 <mx:Script>
  <![CDATA[


   import mx.controls.listClasses.BaseListData;
   import com.esri.ags.samples.LayerTOC;
   
   [Bindable("dataChange")]
   private var _listData:BaseListData;
   
   [Bindable]
   private var SymPath:String = "";
   
   public function get listData():BaseListData
   {
    return _listData;
   }
   
   public function set listData(value:BaseListData):void
   {
    _listData = value;
    if (LayerTOC.SelectedLayerName == "Parcel Boundary")
    {
     switch(listData.label)
     {
      case "Parcel Boundary":
      {
       SymPath = "assets/images/identify.png";
       break;
      }
      default:
      {
       SymPath = null;
       break;
      }
     }
    }
    if (LayerTOC.SelectedLayerName == "Zoning")
    {
     switch(listData.label)
     {
      case "Zoning":
      {
       SymPath = "assets/images/identify.png";
       break;
      }
      default:
      {
       SymPath = null;
       break;
      }
     }
    }
    else
    {
     SymPath = null;
    }
   }
   
  ]]>
 </mx:Script>
 <mx:HBox width="100%" horizontalAlign="center" verticalAlign="middle">
  <mx:Image id="TOCImage" source="{SymPath}" />
 </mx:HBox>
</mx:HBox>


Thanks for your help,
Jason
0 Kudos
RobertScheitlin__GISP
MVP Emeritus
Jason,

    The issue with your code is that the image of the itemRenderer is only set when the dataProvider is set.

So you would have to do this

private function onItemClick(event:ListEvent):void
   {
    SelectedLayerName = this.selectedItem.name;
    setDataProvider();
            }
0 Kudos