Controls in ItemTemplate can't be called in Code Behind

懵懂的女人 提交于 2019-12-10 19:31:55

问题


I have server controls such as a popup with a gridview inside template fields in another gridview:

  <asp:TemplateField HeaderText="Actions">
                <ItemTemplate>
                    <asp:Button ID="viewHoursButton" runat="server" Text="View Hours" OnClick="viewHoursButton_OnClick" />
                    <ajaxToolkit:ModalPopupExtender ID="viewHoursPopup" runat="server"
                        TargetControlID="viewHoursButton"
                        PopupControlID="viewHoursPanel"
                        CancelControlID="closeInfoPanelButton2"
                        DropShadow="true">
                    </ajaxToolkit:ModalPopupExtender>
                    <asp:Panel ID="viewHoursPanel" runat="server" CssClass="infoPanel">
                        <asp:Button ID="closeInfoPanelButton2" runat="server" Text="X" CssClass="closeInfoPanelButton"  />
                        <asp:Label ID="viewHoursLabel" runat="server" Text="Label"></asp:Label>
                        <asp:GridView ID="viewHoursGridView" runat="server" AllowPaging="True" AutoGenerateColumns="False"
                            DataSourceID="SqlDataSource6" DataKeyNames="NonScrumStoryId,PK_DailyTaskHours"
                            BackColor="#DEBA84" BorderColor="#DEBA84" BorderStyle="None" BorderWidth="1px"
                            CellPadding="3" CellSpacing="2" Width="94%" OnRowDeleting="viewHoursGridView_OnRowDeleting"
                            OnRowDataBound="viewHoursGridView_OnRowDataBound" CssClass="centerGridView">
                            <Columns>
                                <asp:BoundField DataField="ActivityDate" HeaderText="Activity Date" SortExpression="ActivityDate"
                                    DataFormatString="{0:MM/dd/yyyy}" />
                                <asp:BoundField DataField="Hours" HeaderText="Hours" SortExpression="Hours" />
                                <asp:BoundField DataField="Notes" HeaderText="Notes" SortExpression="Notes" />
                                <asp:BoundField DataField="CreateDate" HeaderText="Created Date" SortExpression="CreateDate"
                                    Visible="false" />
                                <asp:CommandField ShowDeleteButton="True" />
                            </Columns>
                            <FooterStyle BackColor="#F7DFB5" ForeColor="#8C4510" />
                            <HeaderStyle BackColor="#7fc041" Font-Bold="True" ForeColor="White" />
                            <PagerStyle ForeColor="#8C4510" HorizontalAlign="Center" />
                            <RowStyle BackColor="#FFF7E7" ForeColor="#8C4510" />
                            <SortedAscendingCellStyle BackColor="#FFF1D4" />
                            <SortedAscendingHeaderStyle BackColor="#B95C30" />
                            <SortedDescendingCellStyle BackColor="#F1E5CE" />
                            <SortedDescendingHeaderStyle BackColor="#93451F" />
                        </asp:GridView>
                        <asp:SqlDataSource ID="SqlDataSource6" runat="server" ConnectionString="<%$ ConnectionStrings:ApplicationServices %>"
                            SelectCommand="
                           SELECT [DailyTaskHours].[PK_DailyTaskHours]
                                ,[DailyTaskHours].[NonScrumStoryId]
                                ,[DailyTaskHours].[Hours]
                                ,[DailyTaskHours].[Notes]
                                ,[DailyTaskHours].[ActivityDate]
                                ,[DailyTaskHours].[CreateDate]
                            FROM [NonScrumStory]
                                ,[DailyTaskHours]
                            WHERE [DailyTaskHours].[NonScrumStoryId] = @nonScrumStoryId
                                AND [NonScrumStory].[PK_NonScrumStory] = @nonScrumStoryId
                            ORDER BY [ActivityDate] DESC
                            "
                            DeleteCommand="
                            DELETE
                            FROM [DailyTaskHours]
                            WHERE ([PK_DailyTaskHours] = @setDailyPKDeleteParam)
                            ">
                            <SelectParameters>
                                <asp:QueryStringParameter Name="nonScrumStoryId" Type="String" />
                            </SelectParameters>
                            <DeleteParameters>
                                <asp:QueryStringParameter Name="setDailyPKDeleteParam" Type="Int32" />
                            </DeleteParameters>
                        </asp:SqlDataSource>
                    </asp:Panel>
                    <asp:Button ID="addHoursButton" runat="server" Text="Add Hours" OnClick="addHoursButton_OnClick" />
                    <asp:Button ID="editButton" runat="server" Text="Edit" OnClick="editButton_OnClick" />
                    <asp:Button ID="deleteButton" runat="server" Text="Delete" OnClick="deleteButton_OnClick" />
                </ItemTemplate>
            </asp:TemplateField>

I cant move them out of the gridview because it is necessary for the call to the popup to work correctly.

However my code behind is not recognizing some of the ID's within the ItemTemplate:

protected void viewHoursButton_OnClick(object sender, EventArgs e)
{
    viewHoursPopup.Show();
    viewHoursGridView.DataBind();
}

For example, the _OnClick method work even though the button is inside the ItemTemplate but the two method calls are not recognized:

How do I fix this issue?


回答1:


Use the FindControl() method, but cast them to the more specific type you are using in the ItemTemplate declaration of your markup, like this:

protected void viewHoursButton_OnClick(object sender, EventArgs e)
{
    var viewHoursPopup = parentGridView.FindControl("viewHoursPopup") as ModalPopupExtender;
    var viewHoursGridView = parentGridView.FindControl("viewHoursGridView") as GridView;
    if (viewHoursPopup != null && viewHoursGriView != null)
    {
        viewHoursPopup.Show();
        viewHoursGridView.DataBind();
    }
}

Note: FindControl() returns a Control, which is too general of an object to call the .Show() method. The as operator will return null if the cast cannot be successfully performed, so the check for null later will catch that scenario.




回答2:


protected void viewHoursButton_OnClick(object sender, EventArgs e)
{
    var viewHoursPopup = parentGridView.FindControl("viewHoursPopup")
        as WebControl;
    var viewHoursGridView = parentGridView.FindControl("viewHoursGridView");
    if (viewHoursPopup != null && viewHoursGriView != null)
    {
         viewHoursPopup.Show();
        viewHoursGridView.DataBind();
    }
}

...or...

protected void viewHoursButton_OnClick(object sender, EventArgs e)
{
    var viewHoursButton = (Button)sender;
    var viewHoursPopup = viewHoursButton.Parent.FindControl("viewHoursPopup")
        as WebControl;
    var viewHoursGridView = viewHoursButton.Parent.FindControl("viewHoursGridView");
    if (viewHoursPopup != null && viewHoursGriView != null)
    {
         viewHoursPopup.Show();
        viewHoursGridView.DataBind();
    }
}

Why?

ItemTemplates, RowTemplates, EditTemplates, etc, are all nested in what webforms calls NamingContainers. You cannot access these controls because they are injected dynamically at runtime, their control ID's are not automatically mapped by the codebehind's partial auto-generated class.

There are 2 solutions:

  1. Wrap the content of your Template into a UserControl. That UserControl's codebehind will have compile-time access to any controls that are not further nested into other Templates. To enable interaction between the UserControl and the parent Template that contains it, expose events and public properties on the UserControl

  2. Use .FindControl(string controlID) to "search" the containing control's current Templates to find the control you are looking for. Just be sure to check them against null before trying to invoke anything on them, and that they are cast to the appropriate type based on what methods you intend to invoke on them.



来源:https://stackoverflow.com/questions/19839761/controls-in-itemtemplate-cant-be-called-in-code-behind

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!