Background Info:
For various reasons I'm having to dynamically create a RadioButtonList
in a column of my GridView.
The grid presents the user with a bunch of data on which they have to leave a comment and make a decision on one of 3 radio options:
Naturally, there are a number of rows on the grid. And the way this is to work is the user makes comments and decisions on all the items before saving to the database.
This screen is to be used multiple times, so the radio buttons have to reflect the value that's stored in the database.
The Problem:
Everything works apart from one thing: the radio buttons are always being reset to their initial state (value = 1) because the grid and the controls are being re-created on postback.
Code:
Here's the working code, some of it redacted/edited...
protected void TheGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
[...]
foreach (DataControlFieldCell dc in e.Row.Cells)
{
switch (dc.ContainingField.ToString())
{
[...]
case (_ColReview):
int status = int.Parse(dc.Text);
if (status == 0)
{
dc.Text = "Not sent for review";
}
else
{
var comment = new TextBox();
comment.ID = "ReviewCommentTextBox";
comment.CssClass = "form-control";
comment.Width = 290;
dc.Controls.Add(comment);
var radioButtons = new RadioButtonList();
var rb = new ListItem();
if (status == 2) rb.Selected = true;
rb.Value = "2";
rb.Text = "Yes, Add to Watch List";
radioButtons.Items.Add(rb);
rb = new ListItem();
if (status == 3) rb.Selected = true;
rb.Value = "3";
rb.Text = "No, do not add to Watch List";
radioButtons.Items.Add(rb);
rb = new ListItem();
//initial value in database is 1, hence this will be initially selected
if (status == 1) rb.Selected = true;
rb.Value = "1";
rb.Text = "Skip: no decision";
radioButtons.ID = "RowRadioButtonList";
radioButtons.Items.Add(rb);
dc.Controls.Add(radioButtons);
}
break;
}
}
}
}
protected void BulkupdateLinkButton_Click(object sender, EventArgs e)
{
foreach(GridViewRow gvr in TheGridView.Rows)
{
[...]
int radioItemValue = 0;
foreach (DataControlFieldCell dc in gvr.Cells)
{
string cellName = dc.ContainingField.ToString();
string cellText = dc.Text;
switch(cellName)
{
[...]
case (_ColReview):
TextBox tb = (TextBox)gvr.FindControl("ReviewCommentTextBox");
comment = tb.Text;
RadioButtonList rbl = (RadioButtonList)gvr.FindControl("RowRadioButtonList");
foreach(ListItem li in rbl.Items)
{
//Issue arrives here: selected item is reset on postback, value is always 1
if (li.Selected)
{
radioItemValue = ToolBox.ConvertToInt(li.Value);
}
}
break;
}
}
if (!string.IsNullOrEmpty(comment) && (radioItemValue > 0))
{
if (radioItemValue != 1) // 1 = pending/skip
{
//code to add update the record and save the comment
[...]
}
}
}
}
Idea on solution
Now I can get around this by using a HiddenField
in each row and setting up some JavaScript/JQuery to record the chosen RadioButton but I can't help but think I'm missing a trick here? Can anyone offer up a better/neater solution?