2011-05-16 117 views
4

我正在使用asp.net Ajax Control Toolkit手风琴(http://www.asp.net/ajaxlibrary/act_Accordion.ashx),每个手风琴窗格都包含相当多的lof信息。lazy loading asp.net Ajax Control Toolkit accordion

所有这些信息在页面生成的,但它没有显示,因为该工具包使非活动窗格的

(style="display:none;) 

但因为信息是在页面,它成为一个非常沉重的页面加载。

我正在寻找一种方法来加载窗格按需:所以只有当用户单击窗格的ajax请求发送和窗格加载和展开。

这可以用这个控件来完成,还是我应该选择不同的手风琴?任何帮助或建议表示赞赏。

更新 目前手风琴是用两个嵌套的中继器创建的。第一个中继器遍历类别并为每个类别创建一个面板。第二个中继器在每个面板内重复,获取一个类别的内容并创建面板的内容。

Pleun

+0

您检查了JQuery的手风琴?这可能更适合你想要完成的事情。 – Chad 2011-05-24 18:59:00

回答

1

采取从的DevExpress看看ASPxNavBar控制(免费ASPxperience Suite的一部分)。如果ASPxNavBar的EnableCallBacks属性设置为true,则折叠组的内容未在客户端表示。当一个组第一次被扩展时,它的内容从服务器中被检索出来,然后被缓存在客户端上。组下次扩展时,其内容将从客户端获取,并且不会执行回调服务器。

查看ASPxNavBar - Callbacks (AJAX)在线演示以获取更多信息。

0

我只能建议你是添加了LinkBut​​ton你的头和面板的窗格:

 <Panes> 
      <asp:AccordionPane ID="First" runat="server"> 
       <Header> 
        <asp:LinkButton CommandName="ASD2" ID="LinkButton2" runat="server">LinkButton</asp:LinkButton> 
       </Header> 
       <Content> 
        <asp:Panel ID="Panel2" runat="server" Visible="true"> 
         First 
        </asp:Panel> 
       </Content> 
      </asp:AccordionPane> 
      <asp:AccordionPane ID="Second" runat="server"> 
       <Header> 
        <asp:LinkButton CommandName="ASD" ID="LinkButton1" runat="server">LinkButton</asp:LinkButton> 
       </Header> 
       <Content> 
        <asp:Panel ID="Panel1" runat="server" Visible="false"> 
         Second 
        </asp:Panel> 
       </Content> 
      </asp:AccordionPane> 
     </Panes> 

,并在Accordion1_ItemCommand设定相应的面板Visible财产。

protected void Accordion1_ItemCommand(object sender, CommandEventArgs e) 
+0

感谢您的想法。如何在浏览器中显示Visible = false的面板?它是不是呈现。这也会导致回传或不? – Pleun 2011-05-24 08:09:53

+0

Visible = false的面板不会在服务器上呈现。是的,它会产生回调。您应该为部分页面重绘添加一些逻辑。 – VMAtm 2011-05-24 08:13:49

4

我没有评论和问你的问题。抱歉。 :(
我的问题是关于您打算如何创建和填充手风琴。

你会在IDE中创建使用标记用手窗格或将你绑定的手风琴到将动态创建一个DataSource ?您需要的窗格

,你将有3个不同的数据源或以下的不同组合:
        1)数据源初始化面板的数量和填充只有面板的标题信息。
        2)DataSource填充第一次加载时所有面板的静态内容。
          3.)DataSource填充用户单击展开的单个面板的Lazy-Loaded内容。

随着你的答案,我希望用一个真实的更新这个答案。谢谢。

更新:这个可以通过Ajax Control Toolkit的Accordion实现。
我有一些非常基本代码作为概念验证。它可能会更平滑,但如果您觉得有必要,则可以使用UpdatingProgress控件添加“加载”图像。

手风琴在ASPX标记:
(注意UpdatePanel的 - 你可以使用回调函数替换它们,如果你想,我只是想保持的回答简单)

<asp:Accordion ID="acc_Accordion" runat="server" RequireOpenedPane="false" 
     SelectedIndex="-1" onitemcommand="acc_Accordion_ItemCommand" > 
    <HeaderTemplate> 
     <asp:UpdatePanel ID="up_UpdateHeader" runat="server"> 
      <ContentTemplate> 
      <%--When using "Eval" inside strings for Asp.net controls, 
       you MUST wrap them in apostrophes ('), 
       otherwise with (") you will get parser errors!--%> 
      <asp:LinkButton ID="btn_Header" runat="server" 
       Text='<%# Eval("HeaderText") %>' 
       CommandName="UpdatePane" CommandArgument='<%# Eval("ItemID") %>' 
       Font-Underline="false" ForeColor="Black" 
       style="width:100%; height:100%; cursor:pointer;"/> 
       <%--Use Cursor:Pointer to keep a consistent 
        interface after disabling the button.--%> 
      </ContentTemplate> 
     </asp:UpdatePanel> 
    </HeaderTemplate> 
    <ContentTemplate> 
     <asp:UpdatePanel ID="up_UpdateContent" runat="server" 
         UpdateMode="Conditional"> 
      <ContentTemplate> 
       <%# Eval("ContentText")%> 
       <asp:Label ID="lbl_Content" runat="server" 
        Text="<%# DateTime.Now.ToLongTimeString() %>"></asp:Label> 
      </ContentTemplate> 
     </asp:UpdatePanel> 
    </ContentTemplate> 
</asp:Accordion> 



Page_Load() - 准备我们的“虚拟”数据:

protected void Page_Load(object sender, EventArgs e) 
{ 
    if (IsPostBack == false) 
    { 
     DataTable dt = new DataTable(); 
     dt.Columns.Add("ItemID"); 
     dt.Columns.Add("HeaderText"); 
     dt.Columns.Add("ContentText"); 

     dt.Rows.Add(new object[] { 123456, "Header 1", "Content A." }); 
     dt.Rows.Add(new object[] { 654321, "Header 2", "Content B." }); 

     acc_Accordion.DataSource = new System.Data.DataTableReader(dt); 
     acc_Accordion.DataBind(); 
    } 
} 



的ItemCommand() - 这捕获键式操作的手风琴内:

protected void acc_Accordion_ItemCommand(object sender, CommandEventArgs e) 
{ 
    if (e.CommandName == "UpdatePane") 
    { 
     AjaxControlToolkit.AccordionContentPanel acp 
      = (e as AjaxControlToolkit.AccordionCommandEventArgs).Container; 
     UpdatePanel upHeader 
      = acc_Accordion.Panes[acp.DisplayIndex].HeaderContainer 
      .Controls.OfType<Control>() 
      .Single(c => c is UpdatePanel) as UpdatePanel; 
     LinkButton btn 
      = upHeader.ContentTemplateContainer 
      .Controls.OfType<Control>() 
      .Single(b => b is LinkButton) as LinkButton; 
     UpdatePanel upContent 
      = acc_Accordion.Panes[acp.DisplayIndex].ContentContainer 
      .Controls.OfType<Control>() 
      .Single(c => c is UpdatePanel) as UpdatePanel; 
     Label lbl 
      = upContent.ContentTemplateContainer 
      .Controls.OfType<Control>() 
      .Single(c => c is Label) as Label; 
     lbl.Text = " ID: " + e.CommandArgument 
       + " and Time: " + DateTime.Now.ToLongTimeString(); 
     //You can use the ID from e.CommandArgument to query the database 
     // for data to update your Repeaters with. 
     btn.Enabled = false;//Disabling the button for our Header 
     // will prevent Asyncronous Postbacks to update the content again. 
     //Only disable this if you don't need to update the content 
     // when the user clicks to view the pane again. 
     upContent.Update();//Set UpdateMode="Conditional". 
    } 
} 



我知道这看起来好像很多,不过这只是几行代码(包装和评论前)。

+0

看到我更新的答案,我现在有1 + 2的组合,但这可以改变 – Pleun 2011-05-24 08:08:23

+0

我也想指出,你可以很容易地找到你的控件名称使用下面的代码:Label lbl = upContent.ContentTemplateContainer.FindControl(“ lbl_Content“)作为Label;我更喜欢避免字符串,但可能会比上面的代码执行几个纳秒。 – MikeTeeVee 2011-05-24 22:04:46

+0

嗨迈克,感谢给代码,我用上面的代码工作正常,但我有另一个简单的概念扩大多个窗格,当我单击第二次时间只有折叠单击窗格(已经它只扩展时间),如何处理 – hmk 2013-06-11 11:37:47

2

6 Tips for Working with the ASP.NET AJAX Accordion Control中的技巧4解释了如何确定选定索引何时发生变化。从JavaScript事件处理程序中,您可以执行任何想要更新新选择的手风琴窗格(调用网络服务,使用更新面板等)的内容。

将此与另一篇解释how to use an update panel to refesh content的文章相结合,页面中选择了一个简单的演示:

<ajaxToolKit:Accordion ID="accSample" runat="server" 
RequireOpenedPane="false" SelectedIndex="-1"> 
<Panes> 
    <ajaxToolKit:AccordionPane runat="server"> 
    <Header>Sample</Header> 
    <Content> 
<asp:Button ID="btnSample" runat="server" OnClick="OnShowSample" Style="display: none" /> 
<script type="text/javascript"> 
    Sys.Application.add_load(function (sender, args) { 
    if (!args.get_isPartialLoad()) { 
    var accSample = $find('<%= accSample.ClientID %>_AccordionExtender'); 
    accSample.add_selectedIndexChanged(function (sender, eventArgs) { 
    $get('<%= btnSample.ClientID %>').click(); 
    }); 
    } 
    }); 
</script> 
<asp:UpdatePanel ID="upSample" runat="server"> 
    <ContentTemplate> 
    <asp:DataGrid ID="dgSample" runat="server" Visible="false"/> 
    </ContentTemplate> 
    <Triggers> 
    <asp:AsyncPostBackTrigger ControlID="btnSample" /> 
    </Triggers> 
</asp:UpdatePanel> 
    </Content> 
    </ajaxToolKit:AccordionPane> 
</Panes> 
</ajaxToolKit:Accordion> 

然后在后台代码

protected void OnShowSample(object sender, EventArgs e) 
{ 
dgSample.DataSource = new string[] { "test" }; 
dgSample.DataBind(); 
dgSample.Visible = true; 
} 
+0

你测试这个代码?当控件嵌套在可绑定控件中时,您不能直接从代码隐藏中访问它们,就像您使用dgSample一样,因为可能会有很多实例。您必须从绑定控件的特定实例中挖出它们。查看我的答案,您可能想要更新您的查询来查看您的accSample的当前选定索引,以查找并更新您的dgSample的正确实例。使用它来启动,看看有什么作用:accSample.Panes [accSample.SelectedIndex] .... – MikeTeeVee 2011-05-26 14:22:12

+0

这是所有你需要的,如果你不会疯狂嵌套在中继器。仍然很有用,不是什么问题,但是因为这是延迟加载手风琴的第一个谷歌结果(问题的原始版本),我认为这很好。 – user423430 2011-05-26 22:13:27

+0

你是对的,我没有在那里跳枪。如果你对每个窗格进行硬编码,这就是你所需要的,但是如果你想通过绑定到数据来动态创建你的窗格,那么这个解决方案需要进行调整。根据问题的要求,你的答案很好。我喜欢我的,因为如果您将数据绑定到数据以动态实例化窗格,它会更加健壮。我想我会把你的javascript方法和我的方法结合起来,这样我就可以摆脱头文件中的更新面板。谢谢! – MikeTeeVee 2011-05-27 00:30:11

相关问题