Hi, I need help on how to handle button clicks in an ASP.NET repeater's item when the record on which the item is based is identified by a primary key spanning multiple columns.
The backgrounds:
The page I'm talking about fetches a Complaint
, which is an object with some properties, from the database and displays its properties to the user.
One of this properties is Escalations
, which is a System.Collections.Generic.List<Escalation>
object.
The Escalation
object is merely an in-code representation of the following SQL table:
create table [escalations]
(
[complaint_id] int not null,
[escalation_group_id] varchar (50) not null
[escalation_date] datetime not null,
[escalation_text] text not null,
[response_date] datetime null,
[response_text] text null,
constraint [pk_escalations] primary key ([complaint_id], [escalation_date]),
constraint [fk_complaints] foreign key ([complaint_id]) references [complaints].([complaint_id]),
constraint [fk_escalation_groups] foreign key ([escalation_group_id]) references [escalation_groups].([escalation_group_id])
)
To display the list of Escalations
I choose to use a System.Web.UI.WebControls.Repeater
, because I need a complex layout, so I went with the following code (it's a stripped down version of the actual code to improve readability, e.g. the "Reply to this complaint" part is placed in a modal pop-up, there are validators and so on):
<h2>Complaint #<asp:literal id="complaint_id" runat="server" /></h2>
<asp:repeater id="escalations" runat="server">
<itemtemplate>
<h3>Escalation date</h3>
<p><%# DataBinder.Eval(Container.DataItem, "complaint_date", "{0:yyyy-MM-dd}") %></p>
<h3>Complaint text</h3>
<p><%# DataBinder.Eval(Container.DataItem, "complaint_text") %></p>
<asp:panel id="response_panel" visible='<%# DataBinder.Eval(Container.DataItem, "response_date") == null ? false : true %>' runat="server">
<h3>Response date</h3>
<p><%# DataBinder.Eval(Container.DataItem, "response_date", "{0:yyyy-MM-dd}") %></p>
<h3>Response text</h3>
<p><%# DataBinder.Eval(Container.DataItem, "response_text") %></p>
</asp:panel>
<asp:panel id="reply_panel" visible='<%# DataBinder.Eval(Container.DataItem, "response_date") == null ? true : false %>' runat="server">
<h3>Reply to this complaint</h3>
<p><asp:textbox id="complaint_response" textmode="multiline" runat="server" /></p>
<p><asp:button id="send_response" text="Send response" onclick="SendResponse" runat="server" /></p>
</asp:panel>
</itemtemplate>
</asp:repeater>
When the user clicks on the send_response
button, I need to update the corresponding Escalation
, and I'm at loss on how to identify the correct one.
protected void SendResponse(Object sender, EventArgs e)
{
// ?!?!
}
Getting the complaint_id
is not a big problem, I can save it in the ViewState
since it's the same for every Escalation
.
If the Escalation
would have been identified by a primary key built on a single column, I could have specified a CommandArgument
on the send_response
button, however since the primary key is formed by the complaint_id
and escalation_date
columns, it's not possible to do it.
I even found around solutions involving the bounding of the fields to controls like System.Web.UI.WebControls.Label
or System.Web.UI.WebControls.Literal
, but since the field I need to pass is a DateTime
, I don't know how to handle it.
The question(s):
It is possible to identify - when in the SendResponse
method - the correct Escalation
? If yes, how can I do it? If this is not viable, how can I change the way I display the data?
If someone is eager to read the real sources, here is the ASPX code and here is the C# code, but I must warn you: custom classes and properties, methods names and so on are in Italian.
Thanks in advance, Andrea.