在 Gridview 丢失状态下动态创建单选按钮
Dynamically created RadioButtons in a Gridview losing state
背景信息:
出于各种原因,我不得不在我的 GridView 的列中动态创建一个 RadioButtonList
。
网格向用户展示了一堆数据,他们必须在这些数据上发表评论并在 3 个单选选项中做出决定:
自然地,网格上有许多行。这是工作的方式是用户在保存到数据库之前对所有项目做出评论和决定。
此屏幕要多次使用,因此单选按钮必须反映存储在数据库中的值。
问题:
除一件事外一切正常:单选按钮始终重置为初始状态(值 = 1),因为在回发时重新创建了网格和控件。
代码:
这是工作代码,其中一些 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
[...]
}
}
}
}
解决思路
现在我可以通过在每一行中使用 HiddenField
并设置一些 JavaScript/JQuery 来记录所选的 RadioButton 来解决这个问题,但我不禁觉得我错过了一个技巧这里?谁能提供 better/neater 解决方案?
要将 RadioButtonList
恢复为已保存的选定值,我相信您需要设置列表的 RadioButtonList.SelectedIndex
属性,而不是ListItem
的选定 属性
背景信息:
出于各种原因,我不得不在我的 GridView 的列中动态创建一个 RadioButtonList
。
网格向用户展示了一堆数据,他们必须在这些数据上发表评论并在 3 个单选选项中做出决定:
自然地,网格上有许多行。这是工作的方式是用户在保存到数据库之前对所有项目做出评论和决定。
此屏幕要多次使用,因此单选按钮必须反映存储在数据库中的值。
问题:
除一件事外一切正常:单选按钮始终重置为初始状态(值 = 1),因为在回发时重新创建了网格和控件。
代码:
这是工作代码,其中一些 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
[...]
}
}
}
}
解决思路
现在我可以通过在每一行中使用 HiddenField
并设置一些 JavaScript/JQuery 来记录所选的 RadioButton 来解决这个问题,但我不禁觉得我错过了一个技巧这里?谁能提供 better/neater 解决方案?
要将 RadioButtonList
恢复为已保存的选定值,我相信您需要设置列表的 RadioButtonList.SelectedIndex
属性,而不是ListItem