我正在使用asp.net Ajax Control Toolkit手风琴(http://www.asp.net/ajaxlibrary/act_Accordion.ashx),每个手风琴窗格都包含相当多的信息。
所有信息都在页面中生成但未显示,因为工具包为非活动窗格提供了
(style="display:none;)
但由于信息在页面中,因此加载的页面非常繁重。
我正在寻找一种按需加载窗格的方法:因此,只有当用户单击窗格时,才会发送ajax请求并加载并展开窗格。
这可以通过此控件完成,还是应该选择不同的手风琴?任何帮助或建议表示赞赏。
更新的 目前,手风琴是由两个嵌套的中继器创建的。第一个转发器循环遍历类别,并为每个类别创建一个面板。第二个转发器在每个面板内重复获取一个类别的内容并创建面板的内容。
Pleun
答案 0 :(得分:4)
我没有评论要点并向您提问。抱歉。 :(
我的问题是关于你打算如何创建和填充手风琴。
您是使用IDE中的标记手动创建窗格还是将Accordion绑定到动态创建所需窗格的DataSource?
您是否有3个独立的数据源或以下的不同组合:
1.)DataSource初始化面板数量并仅填充面板的标题信息
2.)DataSource在第一次加载时填充所有面板的静态内容
3.)DataSource用于填充用户单击以展开的单个面板的Lazy-Loaded Content。
有了你的答案,我希望用真实的答案更新这个答案。感谢。
更新:使用Ajax Control Toolkit的Accordion可以实现 。
我在下面有一些非常基本代码作为概念证明。它可能更平滑,但如果您认为有必要,我将使用UpdatingProgress控件添加“加载”图像。
Aspx标记中的手风琴:
(注意UpdatePanels - 如果你愿意,你可以用回调替换它们,我只是想让答案变得简单)
<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() - 这会捕获Accordion中的按钮点击次数:
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".
}
}
我知道这看起来很多,但它只有几行代码(在包装和评论之前)。
答案 1 :(得分:2)
6 Tips for Working with the ASP.NET AJAX Accordion Control中的提示4解释了如何确定所选索引的更改时间。从JavaScript事件处理程序中,您可以执行任何想要更新新选择的折叠窗格的内容(调用Web服务,使用更新面板等)。
在为简单演示选择标签页时,将此与另一篇解释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;
}
答案 2 :(得分:1)
从 DevExpress 查看 ASPxNavBar 控件(免费ASPxperience Suite的一部分)。如果 ASPxNavBar的EnableCallBacks 属性设置为 true ,则折叠组的内容不会在客户端表示。当组首次展开时,将从服务器检索其内容,然后在客户端上缓存。下一次扩展组时,其内容将从客户端获取,并且不会执行对服务器的回调。
查看ASPxNavBar - Callbacks (AJAX)在线演示以获取更多信息。
答案 3 :(得分:0)
我可以建议你将linkButtons添加到你的窗格的标题和面板中:
<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)