Typical solutions to this problem involves creating new controls that are not quite feasible in normal circumstances. There is a simple yet trivial solution to this problem.
The issue is that the ListItem
loses its attributes on postback. However, the List itself never loses any custom attributes. One can take advantage of this in a simple yet effective manner thus.
Steps:
Serialize your attributes using the code in the answer above (https://mcmap.net/q/268682/-listitems-attributes-in-a-dropdownlist-are-lost-on-postback)
Store it to a custom attribute of the ListControl (dropdownlist, checklistbox, whatever).
On post back, read back the custom attribute from the ListControl and then deserialize it back as attributes.
Here is the code I used to (de)serialize attributes (What I needed to do was to keep track of what items of the list were originally rendered as selected when retrieved from the backend and then save or delete rows as per the changes made by the user on the UI):
string[] selections = new string[Users.Items.Count];
for(int i = 0; i < Users.Items.Count; i++)
{
selections[i] = string.Format("{0};{1}", Users.Items[i].Value, Users.Items[i].Selected);
}
Users.Attributes["data-item-previous-states"] = string.Join("|", selections);
(above, "Users" is a CheckboxList
control).
On post back (in my case a Submit button Click event), I use the below code to retrieve the same and store them into a Dictionary for post processing:
Dictionary<Guid, bool> previousStates = new Dictionary<Guid, bool>();
string[] state = Users.Attributes["data-item-previous-states"].Split(new char[] {'|'}, StringSplitOptions.RemoveEmptyEntries);
foreach(string obj in state)
{
string[] kv = obj.Split(new char[] { ';' }, StringSplitOptions.None);
previousStates.Add(kv[0], kv[1]);
}
(PS: I have a library funcs that perform error handling and data conversions, omitting the same here for brevity).