Dynamic Web Button command not firing

G

Guest

I've got a weird problem going on - I've got a table of dynamically created buttons. Each button has the X/Y value of the buttons position in the table assigned to it's CommandArgument property and the name of a common command (btn_Command) assigned to it's Command property. The creation of the table is done by a function called drawGeo. drawGeo is called during the initial Page_Load (!IsPostBack), but should be called by btn_Command on subsequent postbacks, however, it seems that btn_Command is never called when a button is clicked, as I also have two labels, lblX and lblY, that should be set when the btn_Command method is called. All I get is a blank screen with the X & Y values unchanged. I have tried a whole slew of changes, but nothing seems to work right. It's as if btn_Command is never called.

Code below:

public class GeoEdit : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Table Table1;
protected System.Web.UI.WebControls.Label lblX;
protected System.Web.UI.WebControls.Label lblY;
protected System.Web.UI.WebControls.Label lblBtnClicked;
protected dbTier dbt = new dbTier();
private int curX, curY, gridSize;

private void Page_Load(object sender, System.EventArgs e)
{
if (!IsPostBack)
{
Session["curX"] = 400;
Session["curY"] = 300;
Session["gridSize"] = 11;
drawGeo();
}

}

#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion

private void btn_Command(object sender, CommandEventArgs e)
{
string[] cellIndex = e.CommandArgument.ToString().Split(new char[] {';'});
lblBtnClicked.Text = "CellClicked";

curX = int.Parse(cellIndex[0]);
curY = int.Parse(cellIndex[1]);

lblX.Text = "Row: " + curX.ToString();
lblY.Text = "Col: " + curY.ToString();

Session["curX"] = curX;
Session["curY"] = curY;

drawGeo();
}

private void drawGeo()
{
curX = (int)Session["curX"];
curY = (int)Session["curY"];
gridSize = (int)Session["gridSize"];

// calculate player location info
int gridShift = gridSize / 2; // ignore remainder
int x1 = curX - gridShift;
int x2 = curX + gridShift;
int y1 = curY - gridShift;
int y2 = curY + gridShift;

lblX.Text = "X: " + curX;
lblY.Text = "Y: " + curY;

// Get Geo info
// DataTable dtGeo = dbt.getGeo(x1, x2, y1, y2);

for (int rowIndex = y1; rowIndex <= y2; rowIndex++)
{
TableRow tr = new TableRow();
Table1.Rows.Add(tr);

for (int colIndex = x1; colIndex <= x2; colIndex++)
{
TableCell tc = new TableCell();
tr.Cells.Add(tc);
Button btn = new Button();
tc.Controls.Add(btn);
btn.CausesValidation = true;
btn.Text = rowIndex.ToString() + ";" + colIndex.ToString();
btn.CommandArgument = rowIndex.ToString() + ";" + colIndex.ToString();
btn.Command += new CommandEventHandler(btn_Command);
}
}

}
}
 
C

Cliff Harris

Dyanmic buttons are a pain in ASP.Net. I have heard many people say that
ASP.Net, while it allows and supports it, was not really made for dynamic
controls to be inserted.. especially when an event is involved.

The short of it is that in order for an event to be fired on a dynamically
created control on Postback, the control must be re-added to the page at
postback. For you, this means that geoDraw() needs to be call in Page_Load
regardless of whether it is a postback or not.
Stupid? Yes. Inefficient? Yes. But I know of no other way to get an
event fired of a dynamic control.

HTH,
-Cliff

Klom Dark said:
I've got a weird problem going on - I've got a table of dynamically
created buttons. Each button has the X/Y value of the buttons position in
the table assigned to it's CommandArgument property and the name of a common
command (btn_Command) assigned to it's Command property. The creation of the
table is done by a function called drawGeo. drawGeo is called during the
initial Page_Load (!IsPostBack), but should be called by btn_Command on
subsequent postbacks, however, it seems that btn_Command is never called
when a button is clicked, as I also have two labels, lblX and lblY, that
should be set when the btn_Command method is called. All I get is a blank
screen with the X & Y values unchanged. I have tried a whole slew of
changes, but nothing seems to work right. It's as if btn_Command is never
called.
Code below:

public class GeoEdit : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Table Table1;
protected System.Web.UI.WebControls.Label lblX;
protected System.Web.UI.WebControls.Label lblY;
protected System.Web.UI.WebControls.Label lblBtnClicked;
protected dbTier dbt = new dbTier();
private int curX, curY, gridSize;

private void Page_Load(object sender, System.EventArgs e)
{
if (!IsPostBack)
{
Session["curX"] = 400;
Session["curY"] = 300;
Session["gridSize"] = 11;
drawGeo();
}

}

#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);

}
#endregion

private void btn_Command(object sender, CommandEventArgs e)
{
string[] cellIndex = e.CommandArgument.ToString().Split(new char[] {';'});
lblBtnClicked.Text = "CellClicked";

curX = int.Parse(cellIndex[0]);
curY = int.Parse(cellIndex[1]);

lblX.Text = "Row: " + curX.ToString();
lblY.Text = "Col: " + curY.ToString();

Session["curX"] = curX;
Session["curY"] = curY;

drawGeo();
}

private void drawGeo()
{
curX = (int)Session["curX"];
curY = (int)Session["curY"];
gridSize = (int)Session["gridSize"];

// calculate player location info
int gridShift = gridSize / 2; // ignore remainder
int x1 = curX - gridShift;
int x2 = curX + gridShift;
int y1 = curY - gridShift;
int y2 = curY + gridShift;

lblX.Text = "X: " + curX;
lblY.Text = "Y: " + curY;

// Get Geo info
// DataTable dtGeo = dbt.getGeo(x1, x2, y1, y2);

for (int rowIndex = y1; rowIndex <= y2; rowIndex++)
{
TableRow tr = new TableRow();
Table1.Rows.Add(tr);

for (int colIndex = x1; colIndex <= x2; colIndex++)
{
TableCell tc = new TableCell();
tr.Cells.Add(tc);
Button btn = new Button();
tc.Controls.Add(btn);
btn.CausesValidation = true;
btn.Text = rowIndex.ToString() + ";" + colIndex.ToString();
btn.CommandArgument = rowIndex.ToString() + ";" + colIndex.ToString();
btn.Command += new CommandEventHandler(btn_Command);
}
}

}
}
 
Top