Common Add graphics
Common_AddGraphics_CSharp\Default.aspx.cs
// Copyright 2010 ESRI
// 
// All rights reserved under the copyright laws of the United States
// and applicable international laws, treaties, and conventions.
// 
// You may freely redistribute and use this sample code, with or
// without modification, provided you include the original copyright
// notice and use restrictions.
// 
// See the use restrictions.
// 

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class Default : System.Web.UI.Page
{   
    #region Instance Variable Declarations
        private ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection _CallbackResultCollection = new ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection();    
    #endregion

    #region ASP.NET Page Event Handlers

    protected void Page_Load(object sender, System.EventArgs e)
    {
        maptipsCheckBox.CheckedChanged += new EventHandler(maptipsCheckBox_CheckedChanged);
        
        //NOTE: The disabled attribute is added on load. The real problem comes when you have a checkbox like this: <asp:checkbox enabled="false" />. This gets rendered out like this:
        //<span disabled='disabled'><input type='checkbox' disabled='disabled'></span>
        //In our javascript, when we enable the input, we're not enabling the surrounding span. 
        //As it happens, in FireFox, this doesn't seem to be an issue (the checkbox will be enabled as you would expect). 
        //In IE6/7, however, the checkbox will be disabled because the surrounding span is disabled.
        //To get around this, you can do the following instead of saying myCheckBox.Enabled = false in your code-behind:
        //myCheckBox.InputAttributes.Add("disabled", "disabled");
        //(This pertains to ASP.Net 2.0, it may work differently in 1.x)

        maptipsCheckBox.InputAttributes.Add("disabled", "disabled");
        ScriptManager1.RegisterAsyncPostBackControl(maptipsCheckBox);     
        
        if (!ScriptManager1.IsInAsyncPostBack)
        {
            // Set the Session variable indicating whether or not the MapTips have been initialized.  Used
            // because, once the MapTips have been initialized, they only need to be displayed or hidden.
            Session["MapTipsInitialized"] = false;
        }
        System.Collections.Specialized.NameValueCollection requestParameters = Page.Request.Params;
        string requestString = null;

        string controlID = requestParameters["__EVENTTARGET"];

        // Check whether the __EVENTTARGET parameter is null or empty and whether it contains the
        // Toolbar control's ID
        if (!string.IsNullOrEmpty(controlID) && controlID.Contains(Toolbar2.ID))
        {
            requestString = requestParameters["__EVENTARGUMENT"];
            if (requestString.Contains("AddLabels")) //Current tool is custom tool
            {
                // Call the method to create and add new labels
                AddGraphicLabels("ServerResource", "Cities", "AREANAME",
                    "Element Graphics - Labels", "ADFGraphicsResource");

                // Copy callback results from both the Map and the Toc.  The map will contain
                // callback results in the event labels were added, while the Toc will have
                // callback results if the graphics resource or graphics layer containing the
                // labels was created and added to the map
                _CallbackResultCollection.CopyFrom(Map1.CallbackResults);
                _CallbackResultCollection.CopyFrom(Toc1.CallbackResults);
                ScriptManager1.RegisterDataItem(Page, _CallbackResultCollection.ToString(), false);
            }
        }
    }   

    protected void Page_PreRender(object sender, System.EventArgs e)
    {
        // Make sure the page is not in a postback (i.e. is in initial page load)
        // before calling method to add graphics to the map.
        if (!ScriptManager1.IsInAsyncPostBack)
        {
            AddGraphicData();
        }
    }
    #endregion
    
    #region Instance Methods

    // Method that creates and adds two rectangles to the map - one as an element graphic and one as
    // a feature graphic
    protected void AddGraphicData()
    {
        try
        {
            // Retrieve the map functionality for the graphics resource
            ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality graphicsMapFunctionality =
                Map1.GetFunctionality("ADFGraphicsResource") as
                ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality;

            // Check whether the graphics resource was found.  If not, create it.
            if (graphicsMapFunctionality == null)
            {
                ESRI.ArcGIS.ADF.Web.DataSources.IMapResource commonMapResource =
                    CreateGraphicsResource("ADFGraphicsResource");
                graphicsMapFunctionality = (ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality)
                    Map1.GetFunctionality(commonMapResource);

                // Refresh the Toc so it displays the graphics resource
                Toc1.Refresh();
            }

            // Create and name a new ElementGraphicsLayer
            ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer elementGraphicsLayer =
                new ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer();
            elementGraphicsLayer.TableName = "Element Graphics - Extent Rectangle";

            // Get a reference to the graphics resource's graphics dataset
            ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsDataSet graphicsDataSet =
                graphicsMapFunctionality.GraphicsDataSet;

            // Add the newly created element graphics layer to the graphics dataset
            graphicsDataSet.Tables.Add(elementGraphicsLayer);

            // Create a Web ADF polygon and specify its geometry as a rectangle
            ESRI.ArcGIS.ADF.Web.Geometry.Polygon adfElementPolygon = new ESRI.ArcGIS.ADF.Web.Geometry.Polygon();
            adfElementPolygon.Rings.Add(new ESRI.ArcGIS.ADF.Web.Geometry.Ring
                (new ESRI.ArcGIS.ADF.Web.Geometry.Envelope(-100, 20, -80, 40)));

            // Create a fill symbol with a diagonal fill and red boundary
            ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleFillSymbol adfSimpleFillSymbol =
                new ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleFillSymbol();
            adfSimpleFillSymbol.Transparency = 0;
            adfSimpleFillSymbol.FillType = ESRI.ArcGIS.ADF.Web.Display.Symbol.PolygonFillType.FDiagonal;
            adfSimpleFillSymbol.BoundaryColor = System.Drawing.Color.Red;

            // Create a graphic element composed of the rectangle and fill symbols created above
            ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement adfGraphicElement =
                new ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement(adfElementPolygon, adfSimpleFillSymbol);

            // Create another fill symbol.  This one is transparent with no boundary.
            ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleFillSymbol adfSelectedSimpleFillSymbol =
                new ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleFillSymbol();
            adfSelectedSimpleFillSymbol.Color = System.Drawing.Color.Transparent;
            adfSelectedSimpleFillSymbol.BoundaryWidth = 0;

            // Set the graphic element's selected symbol to the transparent fill symbol.
            // The element will be displayed with this fill when selected.
            adfGraphicElement.SelectedSymbol = adfSelectedSimpleFillSymbol;

            // Add the graphic element to the element graphics layer, and get a reference
            // to the row of the data table that represents the element.
            System.Data.DataRow dataRow = elementGraphicsLayer.Add(adfGraphicElement);
            // Make sure the element is not selected.  Do this by setting the data column
            // storing whether or not the element is selected to false.
            dataRow[elementGraphicsLayer.IsSelectedColumn] = false;

            // Create and name a new FeatureGraphicsLayer
            ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer featureGraphicsLayer =
                new ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer();
            featureGraphicsLayer.TableName = "Feature Graphics - Extent Rectangle";

            // Add the feature graphics layer to the graphics resource's graphics dataset
            graphicsDataSet.Tables.Add(featureGraphicsLayer);

            // Create another Web ADF polygon and specify its geometry as a different rectangle
            ESRI.ArcGIS.ADF.Web.Geometry.Polygon adfFeaturePolygon = new ESRI.ArcGIS.ADF.Web.Geometry.Polygon();
            adfFeaturePolygon.Rings.Add(new ESRI.ArcGIS.ADF.Web.Geometry.Ring
                (new ESRI.ArcGIS.ADF.Web.Geometry.Envelope(-70, 20, -50, 40)));

            // Add the polygon to the feature graphics layer
            featureGraphicsLayer.Add(adfFeaturePolygon);

            // Create a Web ADF simple renderer and specify its symbol as the simple fill
            // symbol created above
            ESRI.ArcGIS.ADF.Web.Display.Renderer.SimpleRenderer adfSimpleRenderer =
                new ESRI.ArcGIS.ADF.Web.Display.Renderer.SimpleRenderer();
            adfSimpleRenderer.Symbol = adfSimpleFillSymbol;

            // Symbolize the polygon contained in the feature graphics layer by assigning the
            // simpler renderer to the feature graphics layer.  Note that this is a different
            // pattern than assigning symbology for element graphics layers.  For feature graphics
            // layers, symbology is specified at the layer level.  For element graphics layers,
            // symbology is specified element by element.
            featureGraphicsLayer.Renderer = adfSimpleRenderer;
        }
        catch (System.Exception exception)
        {
            string jsErrorAlert = string.Format("<script>{0}</script>", 
                Utility.GetJavaScriptErrorString(exception));
            Response.Write(jsErrorAlert);
        }
    }

    // Method that creates and adds labels to the map for the current map extent, with parameters
    // defined as follows:
    // sourceResourceName - the name of the map resource containing the layer to generate labels from
    // sourceLayerName - the name of the layer to generate labels from
    // sourceFieldName - the name of the field from which the labels will take their values
    // graphicsLayerName - the name of the graphics layer that will contain the labels
    // graphicsResourceName - the name of the resource containing the label graphics layer
    protected void AddGraphicLabels(string sourceResourceName, string sourceLayerName, 
        string sourceFieldName, string graphicsLayerName, string graphicsResourceName)
    {
        try
        {
            // Retrieve the map functionality for the graphics resource
            ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality graphicsMapFunctionality =
                Map1.GetFunctionality(graphicsResourceName) as
                ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality;

            // Check whether the graphics resource was found.  If not, create it.
            if (graphicsMapFunctionality == null)
            {
                ESRI.ArcGIS.ADF.Web.DataSources.IMapResource commonMapResource =
                    CreateGraphicsResource(graphicsResourceName);
                graphicsMapFunctionality = (ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapFunctionality)
                    Map1.GetFunctionality(commonMapResource);

                // Refresh the Toc so it displays the graphics resource
                Toc1.Refresh();
            }

            // Check whether the graphics layer holding the labels already exists in the graphics resource
            if (graphicsMapFunctionality.GraphicsDataSet.Tables.Contains(graphicsLayerName))
            {
                // Remove the labels graphics layer from the resource.  We will re-create, re-populate, 
                // and re-add the layer based on the current map extent
                graphicsMapFunctionality.GraphicsDataSet.Tables.Remove(graphicsLayerName);
            }

            // Create and name an element graphics layer to contain the labels
            ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer elementGraphicsLayer =
                new ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer();
            elementGraphicsLayer.TableName = graphicsLayerName;

            // Add the element layer to the graphics dataset of the graphics resource
            graphicsMapFunctionality.GraphicsDataSet.Tables.Add(elementGraphicsLayer);

            // Refresh the Toc so it displays the new graphics layer
            Toc1.Refresh();

            // Get a reference to the common API map functionality object for the map resource
            // with the passed-in name.  Note this code assumes such a resource exists.
            ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality commonMapFunctionality =
                (ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality)Map1.GetFunctionality(sourceResourceName);

            // Get the underlying GIS resource from the map functionality
            ESRI.ArcGIS.ADF.Web.DataSources.IGISResource gisResource = commonMapFunctionality.Resource;

            // Use the GIS resource to create a query functionality object to query the resource
            ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality queryFunctionality
                = (ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality)gisResource.CreateFunctionality
                (typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), null);

            // Declare string arrays to store layer IDs and names
            string[] layerIDs;
            string[] layerNames;
            // Get the queryable layers contained in the "ServerResource" map resource via the 
            // query functionality object created by this resource.  Store the output in 
            // the layer ID and name arrays.
            queryFunctionality.GetQueryableLayers(null, out layerIDs, out layerNames);

            // Set the name of the layer to query and that will be used to generate labels
            string queryLayerName = sourceLayerName;

            // Declare a variable to hold the ID of the query layer
            string queryLayerID = null;
            // Iterate through the layer names array to find the ID of the query layer
            for (int index = 0; index < layerNames.Length; index++)
            {
                // Check to see whether the layer name at the current index of the array matches
                // the name of the query layer.  If so, retrieve the ID at the same index from 
                // the layer ID array and assign it to the query layer ID variable
                if (layerNames[index] == queryLayerName)
                {
                    queryLayerID = layerIDs[index];
                    break;
                }
            }

            // Define name of the field to use when labeling
            string labelFieldName = sourceFieldName;

            // Instantiate a Web ADF spatial filter to use in executing the query
            ESRI.ArcGIS.ADF.Web.SpatialFilter adfSpatialFilter =
                new ESRI.ArcGIS.ADF.Web.SpatialFilter();

            // Define the fields to include in the query.  This is done by (1) specifying a
            // delimited string variable containing the list of fields, (2) creating a 
            // StringCollection object from the field list and the delimiter, and (3) passing
            // the StringCollection into the SubFields property of the Web ADF spatial filter.
            // Note that, since the query results will be used to populate the label graphics
            // layer, the fields we specify here will ultimately be the ones included in the layer.
            string fieldList = labelFieldName;
            ESRI.ArcGIS.ADF.StringCollection stringCollection =
                new ESRI.ArcGIS.ADF.StringCollection(fieldList, ',');
            adfSpatialFilter.SubFields = stringCollection;

            // Specify the spatial filter's parameters.  Here we limit the area of the query to
            // the map extent, specify that feature geometries are to be returned with the
            // query results, and limit the number of results returned to be no more than 20.
            adfSpatialFilter.Geometry = Map1.Extent;
            adfSpatialFilter.ReturnADFGeometries = true;
            adfSpatialFilter.MaxRecords = 100;

            // Execute the query and pass the result to a DataTable object
            System.Data.DataTable resultDataTable = queryFunctionality.Query(graphicsMapFunctionality.Name,
                queryLayerID, adfSpatialFilter);

            // Declare a variable to hold the column index of the column in the results DataTable
            // that stores feature geometries
            int geometryColumnIndex = -1;
            // Iterate through the columns of the results table 
            for (int index = 0; index < resultDataTable.Columns.Count; index++)
            {
                // Check whether the type of data stored in the column at the current index
                // is Web ADF geometry.  If so, store the current index as the geometry
                // column index and exit the loop.
                if (resultDataTable.Columns[index].DataType ==
                    typeof(ESRI.ArcGIS.ADF.Web.Geometry.Geometry))
                {
                    geometryColumnIndex = index;
                    break;
                }
            }

            // Iterate through each row of the results table, create a label for the feature
            // the row represents, and add the label to the element graphics layer
            foreach (System.Data.DataRow dataRow in resultDataTable.Rows)
            {
                // Get a reference to the Web ADF geometry stored in the geometry column
                // of the current row
                ESRI.ArcGIS.ADF.Web.Geometry.Geometry adfGeometry =
                    (ESRI.ArcGIS.ADF.Web.Geometry.Geometry)dataRow[geometryColumnIndex];

                // Get the center point of the geometry
                ESRI.ArcGIS.ADF.Web.Geometry.Point adfCenterPoint =
                    ESRI.ArcGIS.ADF.Web.Geometry.Polygon.GetCenterPoint(adfGeometry);

                // Instantiate and initialize a FontInfo object.  This will specify the font
                // of the labels
                ESRI.ArcGIS.ADF.Web.FontInfo fontInfo = new ESRI.ArcGIS.ADF.Web.FontInfo();
                fontInfo.Name = "Arial";                
                fontInfo.Color = System.Drawing.Color.Blue;
                fontInfo.Size = 8;

                // Instantiate a Web ADF text marker symbol
                ESRI.ArcGIS.ADF.Web.Display.Symbol.TextMarkerSymbol adfTextMarkerSymbol =
                    new ESRI.ArcGIS.ADF.Web.Display.Symbol.TextMarkerSymbol();
                // Specify the font of the text marker symbol by passing it the FontInfo object
                adfTextMarkerSymbol.Font = fontInfo;
                // Specify the text of the text marker symbol as the value stored in the label
                // field of the current row
                adfTextMarkerSymbol.Text = (string)dataRow[labelFieldName];

                // Create a graphic element with the center point and text marker symbol and add
                // it to the element graphics layer storing the labels
                ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement graphicElement =
                    new ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement(adfCenterPoint, adfTextMarkerSymbol);
                elementGraphicsLayer.Add(graphicElement);
            }

            // Refresh the graphics resource so any new labels added are displayed
            Map1.RefreshResource(graphicsResourceName);    
        }
        catch (System.Exception exception)
        {
            ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult errorCallbackResult =
                Utility.GetErrorCallback(exception);
            Map1.CallbackResults.Add(errorCallbackResult);
        }
    }

    // Method that toggles map tips on or off via server-side code.  Parameters are defined as follows:
    // showMapTips - whether to show or hide map tips
    // mapTips - the Web ADF MapTips control to interact with
    // resourceName - the name of the map resource containing the layer on which to show map tips
    // layerName - the name of the layer on which to show map tips
    // mapResourceManager - the MapResourceManager control containing the resource indicated by resourceName
    protected void ToggleMapTipsServer(bool showMapTips, string resourceName, string layerName)
    {
        try
        {
            // Get the Session variable indicating whether or not the MapTips have been initialized.
            // If they haven't been, initialize and display them.  If they have been, simply show or 
            // hide them, depending on the value of showMapTips.
            bool mapTipsInitialized = (bool)Session["MapTipsInitialized"];
            // Check whether to display or hide map tips
            if (!mapTipsInitialized)
            {

                // Variable to hold the layer ID of the layer with the passed-in layer name
                string layerID = null;

                // Retrieve a reference to the Common Data Source API MapFunctionality object
                // corresponding to the passed-in resource name
                ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality commonMapFunctionality =
                    Map1.GetFunctionality(resourceName);

                // declare and populate arrays to hold the layer names and IDs in the current resource
                string[] layerNames;
                string[] layerIDs;

                commonMapFunctionality.GetLayers(out layerIDs, out layerNames);

                // Iterate through the layer names array until the passed-in layer name is found.
                // Then retrieve the layer ID at the same index from the layerIDs array and store
                // this for later use.
                for (int i = 0; i < layerNames.Length; i++)
                {
                    if (layerNames[i].ToLower() == layerName.ToLower())
                    {
                        layerID = layerIDs[i];
                        // The layer ID has been found, so exit the loop
                        break;
                    }
                }

                // Make sure a layer ID was found
                if (layerID == null)
                    return;

                // Get the LayerDefinition object for the layer on which map tips will be shown.
                // LayerFormat, which stores the renderer (symbology), visible fields, aliases, 
                // display field, and attribute display format, can be accessed via this object.
                ESRI.ArcGIS.ADF.Web.UI.WebControls.LayerFormat layerFormat =
                    ESRI.ArcGIS.ADF.Web.UI.WebControls.LayerFormat.FromMapResourceManager(
                    MapResourceManager1, resourceName, layerID);

                // Initialize the MapTips control.  At a minimum, the Layer, Map, and LayerFormat properties
                // must be set.  As shown here, the layer must be specified by MapResourceManager ID, resource
                // name, and layer name, in the format <MapResourceManager ID>::<resource name>::<layer name>.
                // This is required because layer name and resource name alone do not necessarily uniquely
                // specify a layer.  Two layers with the same name belonging to resources of the same name
                // can exist in the same application if they belong to different MapResourceManagers.
                MapTips1.Layer = string.Format("{0}::{1}::{2}", MapResourceManager1.ID, resourceName, layerName);
                // Pass in the ID of the map on which map tips will be shown.
                MapTips1.Map = Map1.ID;
                // Enable MapTips to be shown even if layer on which they are based is not visible.
                MapTips1.ShowOnlyWhenLayerIsVisible = false;
                // Use the LayerFormat from the LayerDefinition object initialized above to specify the
                // format of the map tips.
                MapTips1.LayerFormat = layerFormat;
                                
                // Remove the GRAPHICS_ID and IS_SELECTED fields from the map tips.  These are system
                // fields that are present by default in the LayerFormats of feature graphics layers.

                // Declare and initialize variables to store the number of fields in the layer format
                // and the current field index.
                int fieldCount = MapTips1.LayerFormat.Fields.Count;
                int index = 0;

                // Iterate through the fields of the MapTips control's LayerFormat
                for (int i = 0; i < fieldCount; i++)
                {
                    // Check whether the field at the current index is the GRAPHICS_ID or
                    // IS_SELECTED field and remove it from the LayerFormat if so.  Note that,
                    // in this case, we do not increment index.  This is because we have just
                    // removed the field stored at index, therefore the same index will actually
                    // refer to a different field on the next loop iteration.
                    if ((MapTips1.LayerFormat.Fields[index].Name == "GRAPHICS_ID") ||
                        (MapTips1.LayerFormat.Fields[index].Name == "IS_SELECTED"))
                    {
                        MapTips1.LayerFormat.Fields.Remove(MapTips1.LayerFormat.Fields[index]);
                    }
                    else
                    {
                        // The field at the current index is not one of those being sought, so
                        // increment index to move on to the next field.
                        index++;
                    }
                }

                MapTips1.LayerFormat.UseDefaultTitleAndContents = false;
                // Refresh the MapTips control to commit the changes made to its properties
                MapTips1.RefreshMapTips();

                Session["MapTipsInitialized"] = true;
            }
            else
            {
                // MapTips are already initialized, so just toggle the Visible property
                if (showMapTips)
                    MapTips1.Visible = true;
                else
                    MapTips1.Visible = false;
            }

            // Refresh the resource on which the map tips will be shown so that the map tips
            // are displayed or hidden.
            Map1.RefreshResource(resourceName);

            // ADF JavaScript to change active tool in toolbar and map control on client
            string jsToolbarItemDeactivate =  string.Format(@"
                                var toolbar = Toolbars['{0}'];
                                var currentToolField = $get(toolbar.currentToolField);
                                currentToolField.value = '';
                                toolbar.selectTool();
                                toolbar.refreshGroup();
                                $find('{1}').set_mouseMode(ESRI.ADF.UI.MouseMode.Pan);",
                                Toolbar1.ClientID, 
                                Map1.ClientID);

            ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult deactivateToolbarItemsCallbackResult =
                ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsToolbarItemDeactivate);

            Map1.CallbackResults.Add(deactivateToolbarItemsCallbackResult);
           
        }
        catch (System.Exception exception)
        {
            ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult errorCallbackResult =
                Utility.GetErrorCallback(exception);
            Map1.CallbackResults.Add(errorCallbackResult);
        }
    }

    // Function that creates a graphics resource in MapResourceManager1 with the passed-in resourceName.
    // The created resource is returned as a Common Data Source API MapResource object.
    protected ESRI.ArcGIS.ADF.Web.DataSources.IMapResource CreateGraphicsResource(string resourceName)
    {
        // Instantiate and configure a GISResourceItemDefinition to store the definition of the 
        // graphics resource
        ESRI.ArcGIS.ADF.Web.UI.WebControls.GISResourceItemDefinition gisResourceItemDefinition =
            new ESRI.ArcGIS.ADF.Web.UI.WebControls.GISResourceItemDefinition();
        gisResourceItemDefinition.ResourceDefinition = "GraphicsResource";
        gisResourceItemDefinition.DataSourceDefinition = "In Memory";
        gisResourceItemDefinition.DataSourceType = "GraphicsLayer";
        

        // Instantiate and configure a DisplaySettings object to store the display settings
        // of the graphics resource
        ESRI.ArcGIS.ADF.Web.DisplaySettings displaySettings =
            new ESRI.ArcGIS.ADF.Web.DisplaySettings();
        displaySettings.Transparency = 0.0F;
        displaySettings.Visible = true;

        // Instantiate a map resource item
        ESRI.ArcGIS.ADF.Web.UI.WebControls.MapResourceItem mapResourceItem =
            new ESRI.ArcGIS.ADF.Web.UI.WebControls.MapResourceItem();
        // Configure the map resource item with the passed-in resource name, the GIS resource
        // item definition, and the display settings
        mapResourceItem.Name = resourceName;
        mapResourceItem.Definition = gisResourceItemDefinition;
        mapResourceItem.DisplaySettings = displaySettings;

        // Add the map resource item to the map resource manager, and place it above any
        // other resource items
        MapResourceManager1.ResourceItems.Insert(0, mapResourceItem);
        
        // Create and return the graphics resource as an IMapResource object
        return MapResourceManager1.CreateResource(mapResourceItem);
    }

    #endregion

    #region "ASP.NET Web Control Events"

    void maptipsCheckBox_CheckedChanged(object sender, EventArgs e)
    {
        try
        {
            bool isChecked=maptipsCheckBox.Checked;            

            ToggleMapTipsServer(isChecked, "ADFGraphicsResource", "Feature Graphics");

            if (isChecked && (MapTips1.LayerFormat != null))
            {
                // Adjust the appearance of the map tips.  The Title property determines what shows
                // on mouseover and in the map tip's header when the map tip is clicked.  The Contents 
                // property determines what shows in the body of the map tip when clicked.  Field names 
                // in curly braces will be substituted with actual field values at run time.  As shown,
                // HTML can be used to customize the appearance of either the Title or the Contents.
                MapTips1.LayerFormat.Title = "<div style='font-family:Arial; font-weight:bold'>" +
                    "Location: ({X}, {Y})</div>";
                MapTips1.LayerFormat.Contents = "<div style='font-family:Arial; font-size: 9pt; " +
                    "font-weight:bold; color:Red;'>Custom Data Column Value: {CustomDataColumn}</div>";

                // Refresh the resource on which the map tips will be shown so that the updated
                // title and contents formatting is applied.
                Map1.RefreshResource(MapTips1.ResourceName);
            }

            // Copy callback results from both the MapTips control and the Map
            _CallbackResultCollection.CopyFrom(MapTips1.CallbackResults);
            _CallbackResultCollection.CopyFrom(Map1.CallbackResults);
            ScriptManager1.RegisterDataItem(Page, _CallbackResultCollection.ToString(), false);
        }
        catch (System.Exception exception)
        {
            ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult errorCallbackResult =
                Utility.GetErrorCallback(exception);
            _CallbackResultCollection.Add(errorCallbackResult);
        }
    }

    #endregion
}