ArcGIS Add Dynamic Data
ArcGIS_AddDynamicData_CSharp\MoveLayer_ADF.aspx.cs
// Copyright 2011 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.
// 

// Illustrates how the move an existing layer in a pooled ArcGIS Server map service
public partial class MoveLayer_ADF : System.Web.UI.Page
{
    #region Instance Variable Declarations

    private ServerObjectStateModifier _serverObjectStateModifier = null;

    // Specify the name of the resource containing the layer to move
    private string _targetResourceName = "MapResourceItem0";
    // Specify the name of the layer to move
    private string _targetLayerName = "Highways";

    #endregion

    #region ASP.NET Page Life Cycle Event Handlers

    protected void Page_PreInit(object sender, System.EventArgs e)
    {
        // Instantiate a class-level ServerObjectStateModifier to use in moving the layer
        _serverObjectStateModifier = new ServerObjectStateModifier();
    }

    protected void Page_Load(object sender, System.EventArgs e)
    {
        try
        {
            // Register the layer up and down buttons so they initiate asynchronous
            // postbacks when clicked
            ScriptManager1.RegisterAsyncPostBackControl(LayerUpButton);
      ScriptManager1.RegisterAsyncPostBackControl(LayerDownButton);
         
      // If the target layer has been moved (indicated by the session variable storing the moved layer's current index
            // being populated), then we need to move it again to the last index at which it was located so that the Web ADF 
            // components accessing the map resource are aware of the correct layer position.  
            if (Session["currentLayerIndex"] != null)
            {
                // Get the layer's target resource and call the method to move the target layer to its current index, as stored
                // in session
                ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality agsMapFunctionality =
                    (ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality)Map1.GetFunctionality(_targetResourceName);
                ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal mapResourceLocal =
                    (ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal)agsMapFunctionality.Resource;

                _serverObjectStateModifier.MoveLayer(mapResourceLocal, _targetLayerName, (int)Session["currentLayerIndex"]);
            }

            MapResourceManager1.ResourcesDispose += new System.EventHandler(MapResourceManager1_ResourcesDispose);
        }
        catch (System.Exception exception)
    {
      // Check whether the page is loading asynchronously
      if (ScriptManager1.IsInAsyncPostBack)
            {
                // Get a callback result that will show an alert with information pertaining to the exception
                ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult errorCallbackResult =
                    Utility.GetErrorCallback(exception);
                // Get the control that initiated the postback
                System.Web.UI.Control control = Utility.GetPostBackControl(Page);

                // If the control is a Web ADF Control (i.e. WebCotnrol or CompositeControl), add the error 
                // callback to that control's callback results.  Otherwise, add the error callback to the 
                // callback results collection member variable, which will be passed to the client in 
                // GetCallbackResult.
                if (control is ESRI.ArcGIS.ADF.Web.UI.WebControls.WebControl)
                {
                    ESRI.ArcGIS.ADF.Web.UI.WebControls.WebControl adfWebControl = control as
                        ESRI.ArcGIS.ADF.Web.UI.WebControls.WebControl;
                    adfWebControl.CallbackResults.Add(errorCallbackResult);
                }
                else if (control is ESRI.ArcGIS.ADF.Web.UI.WebControls.CompositeControl)
                {
                    ESRI.ArcGIS.ADF.Web.UI.WebControls.CompositeControl adfCompositeControl = control as
                        ESRI.ArcGIS.ADF.Web.UI.WebControls.CompositeControl;
                    adfCompositeControl.CallbackResults.Add(errorCallbackResult);
                }
                else
        {
          ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection callbackResults =
            new ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection();
          callbackResults.Add(errorCallbackResult);
          ScriptManager1.RegisterDataItem(Page, callbackResults.ToString(), false);
                }
            }
            else
            {
                // Since the page is in full postback, write the javascript alert code directly to the response
                string jsErrorAlert = string.Format("<script>{0}</script>",
                    Utility.GetJavaScriptErrorString(exception));
                Response.Write(jsErrorAlert);
            }
        }
    }

    #endregion

    #region Web ADF Control Event Handlers

    void MapResourceManager1_ResourcesDispose(object sender, System.EventArgs e)
    {
        // If the target layer has been moved (indicated by the session variable storing the layer's initial position), then we 
        // need to move it back to its original position in the map resource before the server context created as a result of 
        // the current page request is released.  Otherwise, the target layer will be in the altered position outside the scope
        // of this page request, so clients accessing the map service will see the layer in the new position
        if (Session["originalLayerIndex"] != null)
        {
            // Get the layer's target resource and call the method to move the layer back to its original position
            ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality agsMapFunctionality =
                (ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality)Map1.GetFunctionality(_targetResourceName);
            ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal mapResourceLocal =
                (ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal)agsMapFunctionality.Resource;

            _serverObjectStateModifier.MoveLayer(mapResourceLocal, _targetLayerName, (int)Session["originalLayerIndex"]);
        }
    }

    #endregion

    #region ASP.NET Web Control Event Handlers

  public void LayerUpButton_Click(object sender, System.EventArgs e)
  {
    try
    {
      // Get the resource containing the layer to be moved
      ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal mapResourceLocal = GetResource();

      int currentLayerIndex = GetCurrentlayerIndex(mapResourceLocal);

      // Call the method to move the layer, passing in a layer index one less than the current one, which will move the
      // layer up one position.
      currentLayerIndex = _serverObjectStateModifier.MoveLayer(mapResourceLocal, _targetLayerName, currentLayerIndex - 1);
      if (currentLayerIndex != -1)
      {
        // If a non-negative layer index was returned then the layer was moved successfully.  Update the current layer
        // index session variable and refresh the Map and Toc so they reflect the layer's new position.
        Session["currentLayerIndex"] = currentLayerIndex;
        RefreshMapAndToc();
      }
    }
    catch (System.Exception exception)
    {
      ProcessError(exception);
    }
  }

  public void LayerDownButton_Click(object sender, System.EventArgs e)
  {
    try
    {
      // Get the resource containing the layer to be moved
      ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal mapResourceLocal = GetResource();

      int currentLayerIndex = GetCurrentlayerIndex(mapResourceLocal);

      // Call the method to move the layer, passing in a layer index one more than the current one, which will move the
      // layer up one position.
      currentLayerIndex = _serverObjectStateModifier.MoveLayer(mapResourceLocal, _targetLayerName, currentLayerIndex + 1);
      if (currentLayerIndex != -1)
      {
        // If a non-negative layer index was returned then the layer was moved successfully.  Update the current layer
        // index session variable and refresh the Map and Toc so they reflect the layer's new position.
        Session["currentLayerIndex"] = currentLayerIndex;
        RefreshMapAndToc();
      }
    }
    catch (System.Exception exception)
    {
      ProcessError(exception);
    }
  }

    #endregion

    #region Instance Methods

    // Retrieves the index of the layer indicated by the passed-in name from the passed-in resource
    private int GetLayerIndex(ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal mapResourceLocal, string layerName)
    {
        // Get the map underlying the passed-in map resource
        ESRI.ArcGIS.Carto.IMapServerObjects mapServerObjects =
            (ESRI.ArcGIS.Carto.IMapServerObjects)mapResourceLocal.MapServer;
        ESRI.ArcGIS.Carto.IMap aoMap = mapServerObjects.get_Map(mapResourceLocal.DataFrame);

        // Get a reference to the layer with the passed-in name from the map
        ESRI.ArcGIS.Carto.IEnumLayer enumLayer = aoMap.get_Layers(null, true);
        ESRI.ArcGIS.Carto.ILayer currentLayer = null;
        int layerIndex = 0;
        while ((currentLayer = enumLayer.Next()) != null)
        {
            if (currentLayer.Name == layerName)
                break;

            layerIndex++;
        }

        return layerIndex;
  }

  private int GetCurrentlayerIndex(ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal mapResourceLocal)
  {
    // Get the current index of the layer.  If the session variable storing the layer's original index has not
    // been populated, populate it with the current index.  This will be used to restore the layer to its
    // original position in the map service.
    int currentLayerIndex;
    if (Session["originalLayerIndex"] == null)
    {
      currentLayerIndex = GetLayerIndex(mapResourceLocal, _targetLayerName);
      Session["originalLayerIndex"] = currentLayerIndex;
      Session["currentLayerIndex"] = currentLayerIndex;
    }
    else
      currentLayerIndex = (int)Session["currentLayerIndex"];

    return currentLayerIndex;
  }

    // Refreshes the Map and Toc controls and populates the callback results member variable with the
    // resulting callback results 
    private void RefreshMapAndToc()
    {
        Toc1.Refresh();
        Map1.CallbackResults.CopyFrom(Toc1.CallbackResults);

    Map1.RefreshResource(_targetResourceName);
    ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection callbackResults =
      new ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection();
    callbackResults.CopyFrom(Map1.CallbackResults);
    ScriptManager1.RegisterDataItem(Page, callbackResults.ToString(), false);
    }

  private ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal GetResource()
  {
    ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality agsMapFunctionality =
      (ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality)Map1.GetFunctionality(_targetResourceName);
    return agsMapFunctionality.Resource as
      ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceLocal;
  }

  private void ProcessError(System.Exception exception)
  {
    // Get a callback result that will alert the user of the error and add it to the callback results collection
    ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult errorCallbackResult =
      Utility.GetErrorCallback(exception);
    ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection callbackResults =
      new ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection();
    callbackResults.Add(errorCallbackResult);
    ScriptManager1.RegisterDataItem(Page, callbackResults.ToString(), false);
  }

    #endregion
}