C# ASP.NET:从CodeBehind更新ListView

C# ASP.NET:从CodeBehind更新ListView,c#,asp.net,.net,listview,data-binding,C#,Asp.net,.net,Listview,Data Binding,因此,我的ASP.NET页面上有一个ListView元素,我需要能够从后面的代码中进行更新。据我所知,Microsoft已经准备了UpdatePanels和DataBinding,正是为了实现这一目的,允许我将ListView的内容“绑定”到隐藏代码中的属性成员,并承诺在属性更改时自动更新浏览器的视图(?)。 但是,只有通过GetStuff()的项目初始加载才有效;我可以在调试控制台中看到,我的计时器不断向列表中添加新元素,但这些元素从未出现在浏览器的视图中。我错过了什么 在Default.as

因此,我的ASP.NET页面上有一个ListView元素,我需要能够从后面的代码中进行更新。据我所知,Microsoft已经准备了UpdatePanels和DataBinding,正是为了实现这一目的,允许我将ListView的内容“绑定”到隐藏代码中的属性成员,并承诺在属性更改时自动更新浏览器的视图(?)。 但是,只有通过
GetStuff()
的项目初始加载才有效;我可以在调试控制台中看到,我的计时器不断向列表中添加新元素,但这些元素从未出现在浏览器的视图中。我错过了什么

在Default.aspx中:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="myLittleProject.Default" %>
<%@ Register Src="~/StuffListItemControl.ascx" TagPrefix="stf" TagName="StuffListItem" %>
<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <!-- some irrelevant stuff -->
    </head>
    <bod>
        <form id="form1" runat="server">
            <asp:ScriptManager ID="ScriptManager" runat="server"></asp:ScriptManager>

            <!-- some irrelevant stuff -->

            <asp:UpdatePanel runat="server" ID="StuffUpdatePanel" UpdateMode="Always">
                <ContentTemplate>
                    <ul>
                        <asp:ListView ID="StuffBoundContent" runat="server">
                            <ItemTemplate>
                                <stf:StuffListItem runat="server" ID="StuffListItemControl" />
                            </ItemTemplate>
                        </asp:ListView>
                    </ul>
                </ContentTemplate>
            </asp:UpdatePanel>

            <!-- some more irrelevant stuff -->
        </form>
    </body>
</html>

在Default.aspx.cs中:

using System.Collections.Generic;
namespace myLittleProject
{
    public partial class Default : System.Web.UI.Page
    {
        public static List<Stuff> StuffContent;

        protected void Page_Load(object sender, EventArgs e)
        {
            StuffContent = Stuff.GetStuff(); // returns a list of three elements from the database

            System.Timers.Timer t = new System.Timers.Timer();
            t.Interval = 3000;
            t.Elapsed += T_Tick;
            t.Enabled = true;
        }

        protected void Page_PreRender(object sender, EventArgs e)
        {
            StuffBoundContent.DataSource = StuffContent;
            StuffBoundContent.DataBind();
        }

        private void T_Tick(object sender, EventArgs e)
        {
            StuffContent.Add(new Stuff(StuffContent.Count + 1, DateTime.Now.ToShortDateString(), new string[] { "what", "ever" }));
            System.Diagnostics.Debug.WriteLine("[TIMER EVENT] StuffContent.Count = " + StuffContent.Count.ToString());
        }
    }
}
使用System.Collections.Generic;
名称空间myLittleProject
{
公共部分类默认值:System.Web.UI.Page
{
公共静态列表内容;
受保护的无效页面加载(对象发送方、事件参数e)
{
StuffContent=Stuff.GetStuff();//返回数据库中三个元素的列表
System.Timers.Timer t=新的System.Timers.Timer();
t、 间隔=3000;
t、 已用时间+=t_刻度;
t、 启用=真;
}
受保护的无效页面\u预呈现(对象发送方,事件参数e)
{
StuffBoundContent.DataSource=StuffContent;
StuffBoundContent.DataBind();
}
私有void T_Tick(对象发送方、事件参数e)
{
添加(新内容(StuffContent.Count+1,DateTime.Now.ToSortDateString(),新字符串[]{“what”,“ever”});
System.Diagnostics.Debug.WriteLine(“[TIMER EVENT]StuffContent.Count=“+StuffContent.Count.ToString()”);
}
}
}

System.Timers.Timer不适用于网页。将页面发送到客户端后处理
t
的原因。如果您真的想使用计时器控件,请使用计时器控件

<asp:Timer ID="Timer1" runat="server" OnTick="Timer1_Tick"></asp:Timer>
如果不希望在触发计时器时进行完全回发,请将计时器控件放置在UPdatePanel中

另一件需要记住的事情是,尽管您使用了UpdatePanel,但会触发一个完整的页面生命周期。因此,即使只有ListView更新对用户可见,也会执行页面加载(和PrerRender)中使用的所有其他代码。当每隔几秒钟触发一个updatepanel时,这可能会给服务器带来巨大的负载。也许最好使用Ajax


PS您不需要使用
Page\u PreRender
来绑定数据。

我从没想过这是个问题!我的计时器按预期可靠地将消息打印到调试控制台,但没有发生其他事情。非常感谢,特别是页面生命周期上的提示!
protected void Timer1_Tick(object sender, EventArgs e)
{
    //update the ListView
}