BUG: When you click Edit for the child DataGrid control, nothing happens in Visual Studio .NET 2003 (815004)



The information in this article applies to:

  • Microsoft Visual Studio .NET (2003), Enterprise Developer Edition
  • Microsoft Visual Studio .NET (2003), Enterprise Architect Edition
  • Microsoft Visual Studio .NET (2003), Academic Edition

SYMPTOMS

When your program uses the DataGrid control, and your program has a child DataGrid control that is associated with each row of a parent DataGrid control, a problem may occur. When you click Edit for the child DataGrid control, nothing happens.

CAUSE

Microsoft Visual Studio .NET does not differentiate between events that are generated by a nested DataGrid control.

RESOLUTION

To resolve this problem, your program must be able to differentiate between the events that are generated by the parent DataGrid control and the events that are generated by the child DataGrid control. To do this, put the following code in your program. You must edit the following code to meet the requirements of your program:

WebForm1.aspx.cs

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace MainSub_DataGrid
{
	/// <summary>
	/// Summary description for WebForm1.
	/// </summary>
	public class WebForm1 : System.Web.UI.Page
	{
		protected System.Web.UI.WebControls.DataGrid DataGrid1;
		protected string dgUniqueID = null;
		protected int dgEditItemIndex;
		DataSet dsMain = new DataSet();
		SqlConnection conn = new SqlConnection("User ID=username;password=password;Initial Catalog=Northwind;Data Source=SQLServer;");
	
		private void Page_Load(object sender, System.EventArgs e)
		{

			if(!IsPostBack)
			{
				BindData();
			}

		}

		protected void BindData()
		{
			DataGrid1.DataSource = dsMain;
			DataGrid1.DataBind();
		}


		#region Web Form Designer generated code
		override protected void OnInit(EventArgs e)
		{
			//
			// CODEGEN: ASP.NET Web Form Designer requires this call.
			//
			InitializeComponent();
			base.OnInit(e);

			SqlDataAdapter adapterMain = new SqlDataAdapter();
			adapterMain.SelectCommand = new SqlCommand("Select TOP 3 * From Customers", conn);
			adapterMain.Fill(dsMain, "Customers");

		}
		
		/// <summary>
		/// Required method for Designer support. Do not modify
		/// the contents of this method with code editor.
		/// </summary>
		private void InitializeComponent()
		{    
			this.DataGrid1.ItemCreated += new System.Web.UI.WebControls.DataGridItemEventHandler(this.DataGrid1_ItemCreated);
			this.DataGrid1.CancelCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.DataGrid1_CancelCommand);
			this.DataGrid1.EditCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.DataGrid1_EditCommand);
			this.DataGrid1.UpdateCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.DataGrid1_UpdateCommand);
			this.DataGrid1.ItemDataBound += new System.Web.UI.WebControls.DataGridItemEventHandler(this.DataGrid1_ItemDataBound);
			this.Load += new System.EventHandler(this.Page_Load);

		}
		#endregion

		private void DataGrid1_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
		{
			// Determine whether you are on an Item or on an AlternatingItem. Do not have DataItem for the Header row, the Footer row, or the Pager row of the DataGrid.
			if(e.Item.ItemType.ToString() == "Item" || e.Item.ItemType.ToString() == "AlternatingItem")
			{
				// The following code may vary depending on what your requirements are. The DataSet is created to hold a specific DataTable
				// from the Northwindws table on an SQL Server database. The DataSet permits easy updates also.
				DataSet dsTemp = new DataSet();
				DataGrid dgTemp = new DataGrid();
				// Locate the child DataGrid for the current row of the parent DataGrid (DataGrid1) that is data-bound.
				dgTemp = ((DataGrid)e.Item.FindControl("DataGrid2"));

				// The following three lines demonstrate how to create data access code to perform data retrieval from the Northwindws database.
				SqlDataAdapter adapterTemp = new SqlDataAdapter();
				adapterTemp.SelectCommand = new SqlCommand("SELECT OrderID, CustomerID, ShipVia FROM Orders WHERE CustomerID = '" + ((Label)e.Item.FindControl("lblCustomerID")).Text + "'", conn);
				adapterTemp.Fill(dsTemp, "Orders");

				// Set the DataSource of the child DataGrid (DataGrid2) to the data from the Northwinds database.
				dgTemp.DataSource = dsTemp;
				// Verify whether you have a child DataGrid (DataGrid2) that must be set to edit mode by 
				// interaction from the user.
				if(dgTemp.UniqueID == dgUniqueID)
				{
					// Sets EditItemIndex and resets the UniqueID variable to make sure that this is not run again
					// unless you decide to edit another item on the page.
					dgTemp.EditItemIndex = dgEditItemIndex;
					dgUniqueID = null;
				}

				// Bind data for the child DataGrid (DataGrid2).
				dgTemp.DataBind();
			}
		}

		private void DataGrid1_EditCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
		{
			// Case dgTemp to incoming DataGrid.	
			DataGrid dgTemp = ((DataGrid)source);
			
			// Parent Grid (DataGrid1).
			if(dgTemp.ID.ToString() == "DataGrid1")
			{
				dgTemp.EditItemIndex = e.Item.ItemIndex;
			}
			// Child Grid (DataGrid2).
			else
			{
				dgEditItemIndex = e.Item.ItemIndex;
				dgUniqueID = dgTemp.UniqueID;
			}

			// Re-bind parent DataGrid (DataGrid1).
			BindData();

		}

		private void DataGrid1_ItemCreated(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
		{
			// Look for Items or AlternatingItems of the parent DataGrid to enable event wireup for child DataGrid.
			if(e.Item.ItemType.ToString() == "Item" || e.Item.ItemType.ToString() == "AlternatingItem")
			{
				// Locate child DataGrid.
				DataGrid dgTemp = ((DataGrid)e.Item.FindControl("DataGrid2"));

				// Wireup events that are required for the sample.
				dgTemp.EditCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.DataGridSub_EditCommand);
				dgTemp.CancelCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.DataGridSub_CancelCommand);
				dgTemp.UpdateCommand += new System.Web.UI.WebControls.DataGridCommandEventHandler(this.DataGrid1_UpdateCommand);
			}	
		}

		private void DataGridSub_EditCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
		{
			// Cast dgTemp to incoming DataGrid.
			DataGrid dgTemp = ((DataGrid)source);
			// Store int variable to hold EditItemIndex of the child DataGrid.
			dgEditItemIndex = e.Item.ItemIndex;
			// Store string variable to hold UniqueID of the child DataGrid to be edited.
			dgUniqueID = dgTemp.UniqueID;
			// Re-bind parent (DataGrid1).
			BindData();
		}

		private void DataGrid1_CancelCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
		{
			// Set EditItemIndex to -1 to switch back to ItemTemplate from EditItemTemplate.
			DataGrid1.EditItemIndex = -1;
			// Re-bind parent (DataGrid1).
			BindData();
		}

		private void DataGridSub_CancelCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
		{
			// Case dgTemp to incoming DataGrid.
			DataGrid dgTemp = ((DataGrid)source);
			// Set int variable to enable canceling of Edit mode of the particular child DataGrid.
			dgEditItemIndex = -1;
			// Set string variable to determine the child DataGrid to disable EditItemTemplate.
			dgUniqueID = dgTemp.UniqueID;
			// Re-bind parent DataGrid (DataGrid1).
			BindData();			
		}

		private void DataGrid1_UpdateCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
		{
			// This represents the EventHandler for updating data back to the data source. Code must be added to update the data source
			// that is specific to your environment.
			DataGrid dgTemp = ((DataGrid)source);
			Response.Write("DataGrid being UPDATED - " + dgTemp.ID.ToString() + " : Item - " + e.Item.ItemIndex.ToString());
			DataGrid1.EditItemIndex = -1;
			BindData();
		}

		private void DataGridSub_UpdateCommand(object source, System.Web.UI.WebControls.DataGridCommandEventArgs e)
		{
			// This represents the EventHandler for updating data back to the data source. Code must be added to update the data source
			// that is specific to your environment.
			DataGrid dgTemp = ((DataGrid)source);
			Response.Write("DataGrid being UPDATED - " + dgTemp.ID.ToString() + " : Item - " + e.Item.ItemIndex.ToString());		
			dgEditItemIndex = -1;
			dgUniqueID = dgTemp.UniqueID;
			BindData();
		}
	}
}

WebForm1.aspx

<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="MainSub_DataGrid.WebForm1" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
	<HEAD>
		<title>WebForm1</title>
		<meta content="Microsoft Visual Studio 7.0" name="GENERATOR">
		<meta content="C#" name="CODE_LANGUAGE">
		<meta content="JavaScript" name="vs_defaultClientScript">
		<meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
	</HEAD>
	<body MS_POSITIONING="GridLayout">
		<form id="Form1" method="post" runat="server">
			<asp:datagrid id="DataGrid1" runat="server" AutoGenerateColumns="False">
				<Columns>
					<asp:TemplateColumn>
						<ItemTemplate>
							<asp:LinkButton runat="server" Text="Edit" CommandName="Edit" CausesValidation="false"></asp:LinkButton>
						</ItemTemplate>
						<EditItemTemplate>
							<asp:LinkButton runat="server" Text="Update" CommandName="Update"></asp:LinkButton>&nbsp;
							<asp:LinkButton runat="server" Text="Cancel" CommandName="Cancel" CausesValidation="false"></asp:LinkButton>
						</EditItemTemplate>
					</asp:TemplateColumn>
					<asp:TemplateColumn HeaderText="CustomerID">
						<ItemTemplate>
							<asp:Label ID="lblCustomerID" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.CustomerID") %>'>
							</asp:Label>
						</ItemTemplate>
						<EditItemTemplate>
							<asp:TextBox runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.CustomerID") %>'>
							</asp:TextBox>
						</EditItemTemplate>
					</asp:TemplateColumn>
					<asp:TemplateColumn HeaderText="CompanyName">
						<ItemTemplate>
							<asp:Label runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.CompanyName") %>'>
							</asp:Label>
						</ItemTemplate>
						<EditItemTemplate>
							<asp:TextBox runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.CompanyName") %>'>
							</asp:TextBox>
						</EditItemTemplate>
					</asp:TemplateColumn>
					<asp:TemplateColumn HeaderText="ContactName">
						<ItemTemplate>
							<asp:Label runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.ContactName") %>'>
							</asp:Label>
						</ItemTemplate>
						<EditItemTemplate>
							<asp:TextBox runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.ContactName") %>'>
							</asp:TextBox>
						</EditItemTemplate>
					</asp:TemplateColumn>
					<asp:TemplateColumn HeaderText="Customer Orders">
						<ItemTemplate>
							<asp:DataGrid id="DataGrid2" runat="server" AutoGenerateColumns="True">
								<Columns>
									<asp:TemplateColumn>
										<ItemTemplate>
											<asp:LinkButton runat="server" Text="Edit" CommandName="Edit" CausesValidation="false" ID="Linkbutton1"></asp:LinkButton>
										</ItemTemplate>
										<EditItemTemplate>
											<asp:LinkButton runat="server" Text="Update" CommandName="Update" ID="Linkbutton2"></asp:LinkButton>&nbsp;
											<asp:LinkButton runat="server" Text="Cancel" CommandName="Cancel" CausesValidation="false" ID="Linkbutton3"></asp:LinkButton>
										</EditItemTemplate>
									</asp:TemplateColumn>
									<asp:TemplateColumn HeaderText="OrderID">
										<ItemTemplate>
											<asp:Label runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.OrderID") %>' ID="Label1">
											</asp:Label>
										</ItemTemplate>
										<EditItemTemplate>
											<asp:TextBox runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.OrderID") %>' ID="Textbox1">
											</asp:TextBox>
										</EditItemTemplate>
									</asp:TemplateColumn>
									<asp:TemplateColumn HeaderText="CustomerID">
										<ItemTemplate>
											<asp:Label runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.CustomerID") %>' ID="Label2">
											</asp:Label>
										</ItemTemplate>
										<EditItemTemplate>
											<asp:TextBox runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.CustomerID") %>' ID="Textbox2">
											</asp:TextBox>
										</EditItemTemplate>
									</asp:TemplateColumn>
									<asp:TemplateColumn HeaderText="ShipVia">
										<ItemTemplate>
											<asp:Label runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.ShipVia") %>' ID="Label3">
											</asp:Label>
										</ItemTemplate>
										<EditItemTemplate>
											<asp:TextBox runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.ShipVia") %>' ID="Textbox3">
											</asp:TextBox>
										</EditItemTemplate>
									</asp:TemplateColumn>
								</Columns>
							</asp:DataGrid>
						</ItemTemplate>
						<EditItemTemplate>
							Finish edits to view child DataGrid information.
						</EditItemTemplate>
					</asp:TemplateColumn>
				</Columns>
			</asp:datagrid>
		</form>
	</body>
</HTML>

STATUS

Microsoft has confirmed that this is a bug in the Microsoft products that are listed in the "Applies to" section.

Modification Type:MinorLast Reviewed:2/24/2006
Keywords:kbvs2005swept kbvs2005doesnotapply kbtshoot kbbug KB815004 kbAudDeveloper