Reputation: 1990
Please bear with me if I am not able to properly phrase the question.
This is code which dynamically adds a ListControl (RadioButtonList) to a form:
protected void Page_Load(object sender, EventArgs e)
{
RadioButtonList r = GetRadioButtonList("Status", "Yes, No", "Yes, No", "No, Yes");
form1.Controls.Add(r);
}
private RadioButtonList GetRadioButtonList(string id, string keys, string values, string selectedValues)
{
RadioButtonList list = new RadioButtonList();
list.ID = id;
AddListItems(list, keys, values, selectedValues);
return list;
}
private void AddListItems(ListControl control, string keys, string values, string selectedValues)
{
string[] key = keys.Split(',');
string[] value = values.Split(',');
if (key.Count() == value.Count())
{
for (int i = 0; i < key.Length; i++)
{
ListItem item = new ListItem(key[i].Trim(), value[i].Trim());
control.Items.Add(item);
}
}
foreach (string selectedValue in selectedValues.Split(','))
{
foreach (ListItem item in control.Items)
{
if (item.Value.Trim().Equals(selectedValue.Trim()))
{
item.Selected = true;
}
}
}
}
I have pasted only required, minimum, and reproducible code here.
Since the function AddListItems accepts ListControl and CheckBoxList(ListControl) can have more than one selection, I first accidentally happened to pass two selected values to the RadioButtonList, when replacing the CheckBoxList with the RadioButtonList. It produced unexpected results.
Out of curiosity, I intentionally passed two values as selected items to see what happens.
RadioButtonList r = GetRadioButtonList("Status", "Yes, No", "Yes, No", "No, Yes");
In this case, the item.selected would be called twice. I believe the selected item should be the item which was selected last, which is "Yes".
On debugging, the selected item is "Yes", which is the last one. Fair enough!
Now, when the page is displayed in the browser, "No" is displayed.
What is causing the difference in debugging and actual output?
Edit
Investigating further, I passed three values to check what would happen ...
RadioButtonList r = GetRadioButtonList("Status", "Yes, No, Maybe", "Yes, No, Maybe", "Yes, No, Maybe");
RadioButtonList r = GetRadioButtonList("Status", "Yes, No, Maybe", "Yes, No, Maybe", "Maybe, No, Yes");
RadioButtonList r = GetRadioButtonList("Status", "Yes, No, Maybe", "Yes, No, Maybe", "No, Yes, Maybe");
RadioButtonList r = GetRadioButtonList("Status", "Yes, No, Maybe", "Yes, No, Maybe", "No, Yes");
It did not matter which item was selected last or in whatever order, the last item of the selected items of the RadioButtonList will be displayed as selected.
Edit 2
Thanks to Tim's answer, I ended up with this function.
private void AddListItems(ListControl control, string keys, string values, string selectedValues)
{
string[] key = keys.Split(',');
string[] value = values.Split(',');
if (key.Count() == value.Count())
{
for (int i = 0; i < key.Length; i++)
{
ListItem item = new ListItem(key[i].Trim(), value[i].Trim());
control.Items.Add(item);
}
}
foreach (ListItem item in control.Items)
{
if (control is CheckBoxList)
{
foreach (string selectedValue in selectedValues.Split(','))
{
if (item.Value.Trim().Equals(selectedValue.Trim()))
{
item.Selected = true;
}
}
}
else
{
if (item.Value.Trim().Equals(selectedValues.Split(',').Last().Trim()))
{
item.Selected = true;
break;
}
}
}
}
Upvotes: 0
Views: 2174
Reputation: 460018
The RadioButtonList
does not support multi-selection but you provide "No, Yes" as the selected items. If you want to select the last item ("Yes") only:
RadioButtonList r = GetRadioButtonList("Status", "Yes, No", "Yes, No", "Yes");
You are using your function to return a RadioButtonList
which supports single-selection only. But you are assigning two selected values. Now are you wondering why the "wrong" item is selected. Why?
Item.selected
is called twice, which does not mean two values are assigned. The value is assigned twice. So, why is not the last assigned value displayed in the browser?
Actually the last item is selected, the last item you have added to it's ListItemCollection
, the order of selected items doesn't matter obviously. I think that is just an implementation detail of the browser which renderes the html. If you reverse the order of your two selected items(or just remove one since two are invalid for a RadioButtonList
) it would be the desired result.
Here is the generated HTML in firefox, as you can see both items are "checked" but only the last is actually checked:
<table id="Status">
<tr>
<td><input id="Status_0" type="radio" name="Status" value="Yes" checked="checked" /><label for="Status_0">Yes</label></td>
</tr><tr>
<td><input id="Status_1" type="radio" name="Status" value="No" checked="checked" /><label for="Status_1">No</label></td>
</tr>
</table>
Sidenote: if you want to select ListItems
you don't need to exclude items which should not be selected.
Incorrect if
clause:
foreach (ListItem item in control.Items)
{
if (item.Value.Trim().Equals(selectedValue.Trim()))
{
item.Selected = true;
}
}
The correct code:
foreach (ListItem item in control.Items)
{
item.Selected = item.Value.Trim().Equals(selectedValue.Trim());
}
This also deselects the items correctly.
Upvotes: 1