I am creating a GridView
inside an UpdatePanel
like this:
<asp:ScriptManager runat="server" EnablePartialRendering="true" />
<div id="masterHistoryDialog" style="display: none">
<asp:UpdatePanel runat="server" ChildrenAsTriggers="true" UpdateMode="Always">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="historyRepeater" EventName="PageIndexChanging" />
</Triggers>
<ContentTemplate>
<asp:GridView ID="historyRepeater" AutoGenerateColumns="false" runat="server" AllowPaging="true" AllowSorting="false" PagerSettings-NextPageText="Next" PagerSettings-PreviousPageText="Previous" PageSize="4" OnPageIndexChanging="historyRepeater_PageIndexChanging">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<uc:CustomCalendarControl ChangeID='<%# DataBinder.Eval(Container.DataItem, "Item1") %>' ScheduleID='<%# DataBinder.Eval(Container.DataItem, "Item2") %>' runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
</div>
The PageIndexChanging
event fires as expected, calling the following event handler:
Protected Sub historyRepeater_PageIndexChanging(sender As Object, e As GridViewPageEventArgs)
historyRepeater.PageIndex = e.NewPageIndex
historyRepeater.DataSource = GetSchedules()
historyRepeater.DataBind()
End Sub
CustomCalendarControl
is a custom control.
I confirmed that GetSchedules
is, in fact, getting my entire data set.
I page the data and have 4 custom controls per page (total of 20 items on 5 pages). The first page works correctly. However, when I try to navigate to one of the other pages, the initialization of the custom control fails because it's not getting the actual values of ChangeID
or ScheduleID
- they're always 0.
It fails when I do the call to DataBind()
because initialization of the custom control depends on ChangeID
and ScheduleID
being actual IDs.
How can I fix this issue?
Your problem has to do at which moment the nested User Controls populate its client side content. This happens first for the Control and then the GridView, so the UserControl has already been build before the values of ChangeID
and ScheduleID
are set.
One way to solved this is to manually call the building of the Control from the Parent.
First, modify the UserControl so that it has a public function to properly display the values
public string ChangeID { get; set; }
public string ScheduleID { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
setUCValues();
}
public void setUCValues()
{
Label1.Text = ChangeID;
Label2.Text = ScheduleID;
}
Public Property ChangeID As String
Get
End Get
Set
End Set
End Property
Public Property ScheduleID As String
Get
End Get
Set
End Set
End Property
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
setUCValues
End Sub
Public Sub setUCValues()
Label1.Text = ChangeID
Label2.Text = ScheduleID
End Sub
Next, add an ID
to the UserControl in the GridView
<uc:CustomCalendarControl ID="calendarControl" runat="server" ChangeID=
Then in the PageIndexChanging, loop all the rows and call the function
protected void historyRepeater_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
//databinding
foreach (GridViewRow row in historyRepeater.Rows)
{
WebUserControl1 control = row.FindControl("calendarControl") as WebUserControl1;
control.setUCValues();
}
}
Protected Sub historyRepeater_PageIndexChanging(sender As Object, e As GridViewPageEventArgs)
'databinding
For Each row As GridViewRow In historyRepeater.Rows
Dim control As WebUserControl1 = CType(row.FindControl("calendarControl"),WebUserControl1)
control.setUCValues
Next
End Sub