@Patrick's answer is a good idea, and deserves more credit!. You can have as many data items as you want, they are all separated, and can be used client side if necessary.
They can also be added declaratively rather than in code. I just did this for a GridView like this:
<asp:TemplateField HeaderText="Remind">
<ItemTemplate>
<asp:ImageButton ID="btnEmail"
data-rider-name="<%# ((Result)((GridViewRow) Container).DataItem).Rider %>"
data-rider-email="<%# ((Result)((GridViewRow) Container).DataItem).RiderEmail %>"
CommandName="Email" runat="server" ImageAlign="AbsMiddle" ImageUrl="~/images/email.gif" />
</ItemTemplate>
</asp:TemplateField>
In the RowCommand, you do this:
void gvMyView_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Email")
{
var btnSender = (ImageButton)e.CommandSource;
var riderName = btnSender.Attributes["data-rider-name"];
var riderEmail = btnSender.Attributes["data-rider-email"];
// Do something here
}
}
So much cleaner than hacking all the values together with delimiters and unpacking again at the end.
Don't forget to test/clean any data you get back from the page, in case it's been tampered with!