1

我有一个手风琴,它的一个窗格中有另一个手风琴。这个内部手风琴是使用数据源创建的,因此它的每个窗格都是从对象列表中加载的。在这种特殊情况下,这个数据源也是按需加载的。现在,我卡住的地方是我希望能够仅加载窗格标题,然后在单击窗格时加载内容;类似于我在外窗格中的内容。我在这里感到困惑的原因是,单击窗格时会发生延迟加载,但是由于这发生在数据绑定之后,因此我不知道如何引用调用 ItemCommand 的窗格的内容。不确定这是否有意义。这是内部手风琴:

<ajaxToolkit:Accordion runat="server" ID="accReviewers" OnItemDataBound="accOuterAccordion_ItemDataBound" ContentCssClass="ReviewerContent" RequireOpenedPane="False" SelectedIndex="-1" OnItemCommand="accReviewers_ItemCommand">
            <HeaderTemplate>
                <div>
                    <asp:LinkButton Text='<%#Eval("Header") %>' CssClass="InReviewHeader" runat="server" 
                    CommandName="LoadReviewers" CommandArgument='<%#Eval("MocRequestId") %>'/>    
                </div>
            </HeaderTemplate>
            <ContentTemplate>
                <div>
                    <asp:ListView runat="server" ID="lvReviewers" ItemPlaceholderID="phReviewer" OnItemDataBound="lvReviewers_ItemDataBound">
                        <LayoutTemplate>
                            <div>
                                <asp:HyperLink runat="server" ID="lnkGotoRequest" Text="View this request"/>
                            </div>
                            <asp:PlaceHolder runat="server" ID="phReviewer"/>
                            <div style="margin-top: 5px;">
                                <asp:Button runat="server" ID="btnResubmit" Text="Resubmit" CssClass="ResubmitInitial"/>    
                            </div>
                        </LayoutTemplate>
                        <ItemTemplate>
                            <div class="ReviewerItem">
                                <%#Eval("Assignee.Name") %><br />
                                <img src="" alt="Reviewer" runat="server" ID="imgReviewer" width="75" style="border: 1px solid gray; border-radius: 6px;"/><br />
                                <asp:Label runat="server" ID="lblStatus" Text='<%#Eval("ReviewStatus") %>' />
                                <asp:HyperLink runat="server" ID="lnkRejectComment" CssClass="InitialRejectComment">(details)</asp:HyperLink>
                            </div>
                        </ItemTemplate>
                    </asp:ListView>
                </div>
            </ContentTemplate>
        </ajaxToolkit:Accordion>
    </Content>  
</ajaxToolkit:AccordionPane>

如您所见,手风琴 accReviewers 是通过 DataSource 生成的。在单击 LinkBut​​ton 之前,LayoutTemplate 中包含的列表视图不会绑定其数据源,这将触发 item 命令。还值得注意的是,整个手风琴都包含在一个 UpdatePanel 中。

这是我开始使用的代码,但它似乎没有获得正确的列表视图实例,虽然列表不为空,但它不会显示任何内容:

    protected void accReviewers_ItemCommand(object sender, CommandEventArgs e)
    {
        var mocId = int.Parse(e.CommandArgument.ToString());
        var list = (sender as AjaxControlToolkit.Accordion).FindControl("lvReviewers") as ListView; //APPARENTLY WRONG
        var reviewers = MocApi.GetReviews(mocId); 
        list.DataSource = reviewers;
        list.DataBind();
    }

回顾一下,当单击 HeaderTemplate 中的 LinkBut​​ton 时,我需要以某种方式获得对 ListView 正确实例的引用,以便我可以绑定它的数据源。与往常一样,感谢任何帮助或见解。这与我的上一个问题相似,但特定于在数据绑定之后获得此参考,这似乎有点复杂。TIA

更新:我发现如果我能以某种方式捕获它的索引,我可以绑定项目数据源。我正在探索尝试在内部手风琴的数据绑定期间将其设置为命令参数。

4

1 回答 1

0

我设法用一些小的恶作剧解决了这个问题:

这是标记:

<ItemTemplate>
    <div class="ReviewerItem">
        <%#Eval("Assignee.Name") %><br />
        <div style="display: inline-block; position: relative;">
            <img src="" alt="Reviewer" runat="server" ID="imgReviewer" width="75" style="border: 1px solid lightgray; border-radius: 6px; overflow: hidden;"/><br />    
            <div runat="server" ID="divYes" Visible="False">
                <img src="../Images/Yes.png" alt="Approved" class="ApprovalIcon"  />
            </div>
            <div runat="server" ID="divNo" Visible="False">
                <img src="../Images/No.png" alt="Rejected" class="ApprovalIcon" id="imgNo" />
            </div>
        </div>
        <asp:Label runat="server" ID="lblStatus" Text='<%#Eval("ReviewStatus") %>' />
        <asp:HyperLink runat="server" ID="lnkRejectComment" CssClass="InitialRejectComment">(details)</asp:HyperLink>
        <asp:Panel runat="server" ID="pnlDemoApproval" Visible="False" CssClass="DemoButtons">
            <asp:Button runat="server" ID="btnApprove" Text="Approve" CommandArgument='<%#Eval("Assignee.Guid") + "|" + Eval("Ticketid") %>' CommandName="ApproveReview"/>
            <asp:Button runat="server" ID="btnDeny" Text="Deny" CommandArgument='<%#Eval("Assignee.Guid") + "|" + Eval("Ticketid") %>' CommandName="DenyReview"/>
        </asp:Panel>
        <ajaxToolkit:BalloonPopupExtender runat="server" ID="balloon" BalloonPopupControlID="pnlPopup"
        TargetControlID="lnkRejectComment" Position="TopRight" BalloonStyle="Cloud" BalloonSize="Medium" DisplayOnMouseOver="True"/>
        <asp:Panel runat="server" ID="pnlPopup">Rejection Reason</asp:Panel>
    </div>
</ItemTemplate>

在数据绑定上,我捕获了该项目,以便我可以获取索引并将其设置为 CommandName 以供以后使用:

AjaxControlToolkit.AccordionItemEventArgs e)
{
    if (e.ItemType != AjaxControlToolkit.AccordionItemType.Content) return;
    var index = e.ItemIndex;
    var button = e.AccordionItem.Parent.FindControl("lnkbHeader") as LinkButton;
    if (button != null) button.CommandName = index.ToString();
}

现在该控件包含索引,我可以使用它来定位正确的窗格并绑定其数据源:

protected void accReviewers_ItemCommand(object sender, CommandEventArgs e)
{
    //This seems stupid to put here, but for some reason the item command bypasses the listview catch and passes it to the accordion

    if (e.CommandName == "ApproveReview")
    {
        var assigneeGuid = new Guid(e.CommandArgument.ToString().Split('|')[0]);
        var ticketId = int.Parse(e.CommandArgument.ToString().Split('|')[1]);
        var ticket = new MocApproval(ticketId);
        DoDemoApproval(ticketId, assigneeGuid, true);
        var approvalIndex = (sender as AjaxControlToolkit.Accordion).SelectedIndex;
        var lv =
            (sender as AjaxControlToolkit.Accordion).Panes[approvalIndex].FindControl("lvReviewers") as ListView;
        lv.DataSource = MocApi.GetReviews(ticket.MocRequest);
        lv.DataBind();
        return;
    }
    if (e.CommandName == "DenyReview")
    {
        var assigneeGuid = new Guid(e.CommandArgument.ToString().Split('|')[0]);
        var ticketId = int.Parse(e.CommandArgument.ToString().Split('|')[1]);
        var ticket = new MocApproval(ticketId);
        DoDemoApproval(ticketId, assigneeGuid, false);
        var approvalIndex = (sender as AjaxControlToolkit.Accordion).SelectedIndex;
        var lv =
            (sender as AjaxControlToolkit.Accordion).Panes[approvalIndex].FindControl("lvReviewers") as ListView;
        lv.DataSource = MocApi.GetReviews(ticket.MocRequest);
        lv.DataBind();
        return;
    }

    ...
于 2012-09-04T17:56:56.017 回答