mcl*_*129 5 asp.net viewstate user-controls controls dynamic
我目前正在处理使用动态Web用户控件的应用程序的一部分,并且我在使用ViewState或其他一些不使用ViewState的方法重新实例化回发控件时遇到了一些麻烦.要求我在每次回发时查询数据库.
基本上我在我的页面上有一个用户控件,它包含一个用于保存可变数量的子用户控件的面板和一个显示"Add Control"的按钮,其功能非常自我解释.
子用户控件非常简单; 它只是一个删除按钮,一个下拉菜单和一个排成一排的时间选择器控件.只要用户单击父控件上的"添加控件"按钮,就会向包含子控件的面板添加新的"行".
我想要做的是能够添加和删除对该集合的控制,修改值,并执行我需要在内存中执行的任何操作,而无需对数据库进行任何调用.当我完成添加控件并填充其值时,我想单击"保存"以立即将控件中的所有数据保存/更新到数据库.目前我发现的唯一解决方案是简单地将每个帖子中的数据保存在数据库中,然后使用存储在数据库中的行来重新实例化回发上的控件.显然,这会强制用户根据自己的意愿保存对DB的更改,并且如果他们想要取消使用控件而不保存其数据,则必须进行额外的工作以确保删除先前提交的行.
根据我对使用动态控件的了解,我知道最好在生命周期的Init阶段将控件添加到页面,然后在加载阶段填充它们的值.我还了解到,确保您可以保持控件的视图状态的唯一方法是确保为每个动态控件提供唯一的ID,并确保在重新实例化控件时为其分配完全相同的ID.我还了解到,在生命周期的Init阶段之后,ViewState实际上才会被加载.这就是我的问题所在.如果我无法使用viewstate并且我不想对数据库执行任何调用,如何存储和检索这些控件的名称?是否可以使用ASP.net进行这种内存操作/批量保存值?
任何帮助是极大的赞赏,
麦克风
您可以在会话中保存的集合中存储重新创建控件所需了解的最少内容。会话在页面的初始化阶段可用。
这是给您的一个例子。它包括:
Default.aspx、cs
- 存储用户控件的面板
- “添加控件按钮”,每次单击时都会添加一个用户控件
TimeTeller.ascx, cs
- 有一个名为 SetTime 的方法,它将控件上的标签设置为指定时间。
默认.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="DynamicControlTest._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Panel ID="pnlDynamicControls" runat="server">
</asp:Panel>
<br />
<asp:Button ID="btnAddControl" runat="server" Text="Add User Control"
onclick="btnAddControl_Click" />
</div>
</form>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
默认.aspx.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace DynamicControlTest
{
public partial class _Default : System.Web.UI.Page
{
Dictionary<string, string> myControlList; // ID, Control ascx path
protected void Page_Load(object sender, EventArgs e)
{
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (!IsPostBack)
{
myControlList = new Dictionary<string, string>();
Session["myControlList"] = myControlList;
}
else
{
myControlList = (Dictionary<string, string>)Session["myControlList"];
foreach (var registeredControlID in myControlList.Keys)
{
UserControl controlToAdd = new UserControl();
controlToAdd = (UserControl)controlToAdd.LoadControl(myControlList[registeredControlID]);
controlToAdd.ID = registeredControlID;
pnlDynamicControls.Controls.Add(controlToAdd);
}
}
}
protected void btnAddControl_Click(object sender, EventArgs e)
{
UserControl controlToAdd = new UserControl();
controlToAdd = (UserControl)controlToAdd.LoadControl("TimeTeller.ascx");
// Set a value to prove viewstate is working
((TimeTeller)controlToAdd).SetTime(DateTime.Now);
controlToAdd.ID = Guid.NewGuid().ToString(); // does not have to be a guid, just something unique to avoid name collision.
pnlDynamicControls.Controls.Add(controlToAdd);
myControlList.Add(controlToAdd.ID, controlToAdd.AppRelativeVirtualPath);
}
}
}
Run Code Online (Sandbox Code Playgroud)
报时器.ascx
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="TimeTeller.ascx.cs" Inherits="DynamicControlTest.TimeTeller" %>
<asp:Label ID="lblTime" runat="server"/>
Run Code Online (Sandbox Code Playgroud)
报时器.ascx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace DynamicControlTest
{
public partial class TimeTeller : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
public void SetTime(DateTime time)
{
lblTime.Text = time.ToString();
}
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
lblTime.Text = (string)ViewState["lblTime"];
}
protected override object SaveViewState()
{
ViewState["lblTime"] = lblTime.Text;
return base.SaveViewState();
}
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我仍然需要管理用户控件的内部视图状态,但是视图状态包被保存到页面并在回发时交回给控件。我认为重要的是要注意我的解决方案与大卫的解决方案非常接近。我的示例中唯一的主要区别是它使用会话而不是视图状态来存储控制信息。这允许在初始化阶段发生一些事情。需要注意的是,此解决方案会占用更多服务器资源,因此在某些情况下可能不合适,具体取决于您的扩展策略。
| 归档时间: |
|
| 查看次数: |
4457 次 |
| 最近记录: |