此网页应如下:
调用populateTeamMembers(),它首先检查数据表是否没有行(表明这是第一次调用该函数),以防它查询SQL以查看谁是现有团队成员,加载进入数据表sqlTeamMembers
此函数还检查第二个数据表newTeamMembers中是否有任何行,如果是,则将newTeamMembers的内容合并到sqlTeamMembers中。第一次加载页面时,newTeamMembers数据表应始终为空,因此不会执行合并。
最后,既然sqlTeamMembers应该包含我们需要的每个人,它会将它绑定到gridview以显示在网页上。
显示后,网格视图下方会显示一个下拉列表,其中包含可添加到团队中的员工列表。如果在ddl上更改了所选索引,则会收到回发并调用selectedIndexChanged()。
selectedIndexChanged()中的逻辑是它将选定的个人信息查询到数据表中,如果用户已经分配给不同的团队,则警告用户,并继续将员工添加到newTeamMembers数据表中。
最后,再次调用populateTeamMembers(),这次newTeamMembers数据表中有数据,并且在再次绑定到gridView之前执行合并。
由于两个数据表sqlTeamMembers和newTeamMembers的性质,我已经在我的班级头部初始化它们,因此所有函数都可以访问它们。
它可以为sqlTeamMembers添加一个新行,但如果我尝试继续第二次添加,它就会消除第一个添加。 由于某种原因,newTeamMembers没有保留新行,它只包含selectedIndexChanged()创建的最新添加。
每次调用selectedIndexChanged()时,如何让newTeamMembers保留新行?
public partial class Personnel_Admin_Teams : System.Web.UI.Page
{
SqlConnection cnn = new SqlConnection(ConfigurationManager.ConnectionStrings["WebServerConnectionString"].ConnectionString);
SqlDataReader myreader = default(SqlDataReader);
SqlCommand cmd = new SqlCommand();
string sqlStr;
DataTable sqlTeamMembers = new DataTable();
DataTable newTeamMembers = new DataTable();
...
protected void populateTeamMembers(string TeamID)
{
if (sqlTeamMembers.Rows.Count == 0)
{
/*** Read Team Members with Matching TeamID from Employees Table ***/
cnn.Open();
sqlStr = "SELECT [ID], [LastName]+', '+[FirstName] AS [Name], ISNULL([TeamRole], '') AS [TeamRole] FROM [Employees] WHERE [TeamID] = " + TeamID + ";";
cmd = new SqlCommand(sqlStr, cnn);
sqlTeamMembers.Load(cmd.ExecuteReader());
cnn.Close();
}
if (newTeamMembers.Rows.Count > 0)
{
sqlTeamMembers.Merge(newTeamMembers);
}
gvTeamMembers.DataSource = sqlTeamMembers;
gvTeamMembers.DataBind();
try
{
for (int i = 0; i < gvTeamMembers.Rows.Count; i++)
{
DropDownList ddlTeamRole = gvTeamMembers.Rows[i].Cells[2].FindControl("ddlTeamRole") as DropDownList;
string txtTeamRole = sqlTeamMembers.Rows[i][2].ToString();
txtTeamRole = txtTeamRole.Replace("'", "''");
ddlTeamRole.SelectedValue = txtTeamRole;
}
}
catch (Exception ex)
{
ScriptManager.RegisterClientScriptBlock(Page, typeof(Page), "class", "alert(\"There was an error: " + ex + "\");", true);
}
}
selectedIndexChanged()
{
cnn.Open();
sqlStr = "SELECT [ID], [LastName]+', '+[FirstName] AS [Name], ISNULL([TeamRole], '') AS [TeamRole], ISNULL([TeamID], '0') FROM [Employees] WHERE [ID] = " + ddlAllEmployees.SelectedValue + ";";
cmd = new SqlCommand(sqlStr, cnn);
DataTable addOneMember = new DataTable();
addOneMember.Load(cmd.ExecuteReader());
cnn.Close();
int empTeamID = Convert.ToInt32(addOneMember.Rows[0][3]);
/*** If DT has not been used yet, establish columns ***/
if (newTeamMembers.Columns.Count == 0)
{
newTeamMembers.Columns.Add("ID", typeof(int));
newTeamMembers.Columns.Add("Name", typeof(string));
newTeamMembers.Columns.Add("TeamRole", typeof(string));
}
/*** Remove TeamID Column before merging data back to primary DataTable, perform merge ***/
addOneMember.Columns.RemoveAt(3);
newTeamMembers.Merge(addOneMember);
if (empTeamID != 0)
{
sqlStr = "SELECT [TeamLocation]+' | '+[Department]+' | '+[Type]+' | '+[Team]+' | '+[Shift] AS [Team] FROM [Teams] WHERE [ID] =" + empTeamID + ";";
cmd = new SqlCommand(sqlStr, cnn);
cnn.Open();
myreader = cmd.ExecuteReader();
myreader.Read();
string existingTeam = myreader[0].ToString();
myreader.Close();
cnn.Close();
ScriptManager.RegisterClientScriptBlock(Page, typeof(Page), "class", "alert(\"Warning: User is currently assigned to another team. Employee will be removed from " + existingTeam + " when you save this page.\");", true);
}
}
答案 0 :(得分:1)
您需要了解一些事项。
网页是无状态的,这意味着它的初始传递和后续的PostBacks,你负责通过一些持久性媒介保存和恢复状态。
许多服务器控件可以为您执行此操作,但您选择通过DataTables管理所有这些,因此您需要实现数据持久性。对于数据库查询结果,SqlDataSource控件使用应用程序缓存。您应该以编程方式使用它:
public partial class Personnel_Admin_Teams : System.Web.UI.Page { DataTable sqlTeamMembers = null; DataTable newTeamMembers = null; protected void Page_Load( object sender, EventArgs e ) { if( !Page.IsPostBack ){ if( Application.Cache["sqlTeamMembers"] == null ) Application.Cache["sqlTeamMembers"] = new DataTable(); if( Application.Cache["newTeamMembers"] == null ) Application.Cache["newTeamMembers"] = new DataTable(); } sqlTeamMembers = (DataTable) Application.Cache["sqlTeamMembers"]; newTeamMembers = (DataTable) Application.Cache["newTeamMembers"]; // NOTE: sqlTeamMembers will be null until you make that call to // populateTeamMembers() so there is no hard and fast rule // about binding during PageLoad. Bind every time you need // to reflect changes. gvTeamMembers.DataSource = sqlTeamMembers; gvTeamMembers.DataBind(); } }
另外,只是为了验证,DataTables不是实时的,打开了与数据库的连接。对DataTable的更改不会自动写回您的数据库。您必须进行适当的INSERT / UPDATE SQL调用。
答案 1 :(得分:0)
我认为问题在于这一行的位置:
DataTable newTeamMembers = new DataTable();
由于它在课程开始时,每次加载页面时都会运行,这意味着每次您加载页面,包括页面是回发时。例如,当用户单击按钮添加新的团队成员时,就会发生回发。然后将该页面发回服务器,并包含用户条目。
您正在寻找的行为是初始化新的newTeamMembers
第一次页面加载,但不当页面是回发时。要解决此问题,请在类的顶部声明newTeamMembers
,但仅在页面不是回发时初始化它,方法是在页面加载事件中检查:
public partial class Personnel_Admin_Teams : System.Web.UI.Page
{
DataTable newTeamMembers;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack) //page is loaded for the first time
{
newTeamMembers = new DataTable();
}
}
//rest of the code
}