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