Common Context menu
Common_ContextMenu_CSharp\SimpleTaskResults.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.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class SimpleTaskResults : System.Web.UI.Page
{
    ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenuItem dynamicContextMenuItem;

    protected void Page_Load(object sender, System.EventArgs eventArgs)
    {
        // Custom context menu event handlers to process event when item clicked and reset display of node is content menu dismissed.
        ContextMenu1.ItemClicked += new ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenuItemClickedEventHandler(ContextMenu1_ItemClicked);
        ContextMenu1.Dismissed += new ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenuDismissedEventHandler(ContextMenu1_Dismissed);
           
        // The ContextMenu control does not expose the delegates for ContextMenuItemClickedEventHandler.  If it
        // did, you could reorder the sequence in which the delegates (event methods) are called.  In general though, 
        // the delegates shouldn't need to be exposed publicly since the order of delegates shouldn't matter.  As a 
        // result of this limitation, event handlers added to context menus during the creation of the TaskResults 
        // control are added first and handlers added subsequent to creation of the TaskResults control are added 
        // after.  When the event is triggered, the handlers are called in sequence from the first added to the last.  
        // Thus the custom event handler referenced in the line below is called after any handlers added within the 
        // TaskResults class itself.  So if the first handler modifies properties or components necessary for subsequent 
        // handlers, we must override the context menu item (see ModifyFeatureContextMenu() method).
        TaskResults1.FeatureContextMenu.ItemClicked +=
            new ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenuItemClickedEventHandler(FeatureContextMenu_ItemClicked);
        TaskResults1.NodeRemoved +=
            new ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNodeRemovedEventHandler(TaskResults1_NodeRemoved);
    }

    protected void Page_PreRender(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            ContextMenu1.Items.Clear();
            ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenuItem showAlertContextMenuItem = 
                new ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenuItem();
            showAlertContextMenuItem.Text = "Show Alert";
            showAlertContextMenuItem.ImageUrl = "images/alertlink.gif";
            ContextMenu1.Items.Add(showAlertContextMenuItem);
            ContextMenu1.Items.Add(TaskResults1.RemoveOnlyContextMenu.Items[0]);

            // Only occurs on initial page request (not postback).  
            // TaskResults CreateChildControls() called during control Load event.
            ModifyFeatureContextMenu();
        }
    }

    void ContextMenu1_Dismissed(object sender, ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenuDismissedEventArgs args)
    {
        ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode node = TaskResults1.Nodes.FindByNodeID(args.Context);
        if (node != null)
        {
            // Unselect node in TaskResults
            ContextMenu1.CallbackResults.Add(new ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult(this, "javascript",
                string.Format("var node=document.getElementById('{0}_textCell');if(node!=null){{node.style.backgroundColor='{1}';}}",
                node.NodeID, System.Drawing.ColorTranslator.ToHtml(TaskResults1.BackColor))));
        }
    }

    void ContextMenu1_ItemClicked(object sender, ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenuItemEventArgs contextMenuItemEventArgs)
    {
        ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode treeViewPlusNode = TaskResults1.Nodes.FindByNodeID(contextMenuItemEventArgs.Context);
        ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult callbackResult = null;

        switch (contextMenuItemEventArgs.Item.Text)
        {
            case "Show Alert":
                callbackResult = new ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult
                    (null, null, "javascript", "alert('Hello')");
                ContextMenu1.CallbackResults.Add(callbackResult);
                break;
            case "Remove":
                treeViewPlusNode.Parent.Nodes.Remove(treeViewPlusNode);
                TaskResults1.Refresh();
                ContextMenu1.CallbackResults.CopyFrom(TaskResults1.CallbackResults);
                break;
            case "Dynamic Show Alert":
                callbackResult = new ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult
                    (null, null, "javascript", "alert('Dynamic Hello')");
                ContextMenu1.CallbackResults.Add(callbackResult);
                break;
        }
    }

    protected void Toolbar1_CommandClick(object sender, ESRI.ArcGIS.ADF.Web.UI.WebControls.ToolbarCommandClickEventArgs toolbarCommandClickEventArgs)
    {
        foreach (ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenuItem contextMenuItem in ContextMenu1.Items)
        {
            if (contextMenuItem.Text == "Dynamic Show Alert")
            {
                dynamicContextMenuItem = contextMenuItem;
            }
        }

        // name of the Command in the Toolbar
        switch (toolbarCommandClickEventArgs.CommandName)
        {
            case ("AddNode"):

                if (dynamicContextMenuItem != null)
                    ContextMenu1.Items.Remove(dynamicContextMenuItem);

                ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskResultNode headingTaskResultNode =
                    new ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskResultNode("Heading");

                ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode detailTreeViewPlusNode =
                    new ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode("Detail");
                TaskResults1.SetupContextMenu(ContextMenu1, detailTreeViewPlusNode);
                headingTaskResultNode.Nodes.Add(detailTreeViewPlusNode);
                detailTreeViewPlusNode.EnsureVisible();

                // Only necessary because dynamic context menu items may have been added\removed
                //ContextMenu1.Refresh();
                Toolbar1.CallbackResults.CopyFrom(ContextMenu1.CallbackResults);

                TaskResults1.DisplayResults(null, null, null, headingTaskResultNode);
                Toolbar1.CallbackResults.CopyFrom(TaskResults1.CallbackResults);
                break;

            case ("AddNodeWithDynamicItem"):

                if (dynamicContextMenuItem == null)
                {
                    dynamicContextMenuItem = new ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenuItem();
                    dynamicContextMenuItem.Text = "Dynamic Show Alert";
                    dynamicContextMenuItem.ImageUrl = "images/wrench.gif";
                    ContextMenu1.Items.Add(dynamicContextMenuItem);
                    //ContextMenu1.Refresh();
                }                

                ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskResultNode dymamicHeadingTaskResultNode =
                    new ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskResultNode("Heading");

                ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode dynamicDetailTreeViewPlusNode =
                    new ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode("Dynamic Node Detail");
                TaskResults1.SetupContextMenu(ContextMenu1, dynamicDetailTreeViewPlusNode);
                dymamicHeadingTaskResultNode.Nodes.Add(dynamicDetailTreeViewPlusNode);
                dynamicDetailTreeViewPlusNode.EnsureVisible();

                
                TaskResults1.DisplayResults(null, null, null, dymamicHeadingTaskResultNode);
                Toolbar1.CallbackResults.CopyFrom(TaskResults1.CallbackResults);

                break;
        }
    }

    // Fired when a node is removed from the TaskResults control
    void TaskResults1_NodeRemoved(object sender,
        ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNodeRemovedEventArgs treeViewPlusNodeRemovedEventArgs)
    {
        // Store the removed node and its parent in session
        Session["RemovedNode"] = treeViewPlusNodeRemovedEventArgs.Node;
        Session["RemovedNodeParent"] = treeViewPlusNodeRemovedEventArgs.Parent;
    }

    // Check context menu items on TaskResults FeatureContextMenu for existing custom item 
    protected bool contextMenuPredicateHandler(ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenuItem target)
    {
        if (target.Text == "Remove Node")
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    // Adds a context menu item for removing the current node from the TaskResults control
    // Called during PreRender
    private void ModifyFeatureContextMenu()
    {
        System.Predicate<ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenuItem> contextMenuPredicate = 
            new System.Predicate<ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenuItem> (contextMenuPredicateHandler);
        if (!TaskResults1.FeatureContextMenu.Items.Exists(contextMenuPredicate))
        {
            ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenuItem deleteNodeContextMenuItem =
                new ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenuItem();
            deleteNodeContextMenuItem.Text = "Remove Node";
            deleteNodeContextMenuItem.ImageUrl = "images/delete.gif";

            TaskResults1.FeatureContextMenu.Items.Add(deleteNodeContextMenuItem);
        }
    }

    // Fires when a context menu item is clicked
    void FeatureContextMenu_ItemClicked(object sender, ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenuItemEventArgs
        contextMenuItemEventArgs)
    {
        // Get the clicked node
        ESRI.ArcGIS.ADF.Web.UI.WebControls.FeatureNode featureNode = (ESRI.ArcGIS.ADF.Web.UI.WebControls.FeatureNode)
            TaskResults1.Nodes.FindByNodeID(contextMenuItemEventArgs.Context);
        ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode parentNode = null;
        ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenu contextMenu = null;
        ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskResults taskResults = null;

        // Check which context menu item was clicked
        switch (contextMenuItemEventArgs.Item.Text)
        {
            // Preconfigured with the TaskResults context menus, thus the node has already been removed.  
            // The NodeRemoved event has already fired.
            case "Remove":
                contextMenu = (ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenu)sender;
                featureNode = (ESRI.ArcGIS.ADF.Web.UI.WebControls.FeatureNode)Session["RemovedNode"];

                if (featureNode != null)
                {
                    parentNode = (ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode)Session["RemovedNodeParent"];
                    parentNode.Refresh();
                    taskResults = (ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskResults)contextMenuItemEventArgs.Control;
                    contextMenu.CallbackResults.CopyFrom(taskResults.CallbackResults);
                }
                break;

            // Custom context menu item, thus explicit removal is required.
            // The NodeRemoved event when Remove method is called on feature node.
            case "Remove Node":

                if (featureNode != null)
                {
                    if (Map1 != null)
                    {
                        contextMenu =
                            (ESRI.ArcGIS.ADF.Web.UI.WebControls.ContextMenu)sender;

                        // Delete data row associated with feature node
                        System.Data.DataRow dataRow = featureNode.DataRow;
                        dataRow.Delete();

                        // Refresh map resource that displays feature associated with feature node
                        if (dataRow.Table is ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer && dataRow.Table.DataSet != null &&
                            (!string.IsNullOrEmpty(dataRow.Table.DataSet.DataSetName)))
                        {
                            Map1.RefreshResource(dataRow.Table.DataSet.DataSetName);

                            // Context menu is responsible from generating callback response, thus
                            // copy callback results to context menu callback results collection.
                            contextMenu.CallbackResults.CopyFrom(Map1.CallbackResults);
                        }

                        // Refresh node within TaskResults 
                        parentNode =
                             (ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode)featureNode.Parent;

                        // Delete the feature node from the TaskResults display
                        featureNode.Remove();

                        parentNode.Refresh();

                        taskResults =
                            (ESRI.ArcGIS.ADF.Web.UI.WebControls.TaskResults)contextMenuItemEventArgs.Control;

                        // Context menu is responsible from generating callback response, thus
                        // copy callback results to context menu callback results collection.
                        contextMenu.CallbackResults.CopyFrom(taskResults.CallbackResults);
                    }
                }
                break;
        }
    }
}