我有一个包含gridview的ASP.NET页面。
我必须根据数据表,某些字段类型信息和一些标题文本动态创建列。
我是通过创建模板来实现的。
它创建了网格很好并且看起来都很好,但是当我单击一个复选框并且checkedchanged事件触发时会发生奇怪的事情
我第一次点击它的罚款,我得到了事件中的预期值
但第二次然后事件被第一次使用的值触发,然后使用我实际点击的复选框中的值再次触发..第三次事件被触发3次,前2次用旧值和第三个值正确。
它就像那样继续前进
所以我很难过!
以下代码我希望有人能看到我做错了什么:
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
namespace GridTest
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
DoTheGridView();
}
public void CreateGrid(DataTable table, string[] types, string[] headers)
{
try
{
for (int i = 0; i < table.Columns.Count; i++)
{
TemplateField field = new TemplateField();
//header template
field.HeaderTemplate = new GridViewHandler(ListItemType.Header, table.Columns[i].ColumnName, types[i], headers[i]);
//item template
field.ItemTemplate = new GridViewHandler(ListItemType.Item, table.Columns[i].ColumnName, types[i], headers[i]);
//edit template
field.EditItemTemplate = new GridViewHandler(ListItemType.EditItem, table.Columns[i].ColumnName, types[i], headers[i]);
grid.Columns.Add(field);
}
}
catch (Exception)
{
throw;
}
}
public void DoTheGridView()
{
DataTable table = SqlHelper.GetData();
string[] types = Regex.Split("String,String,String,String,String,CheckBox", ",");
string[] headers = Regex.Split("UserID,License Key,Name,Company,Email,Xpress", ",");
CreateGrid(table, types, headers);
table.DefaultView.RowFilter = "navn like 'Anders%'";
table.DefaultView.Sort = "navn DESC";
grid.DataSource = table.DefaultView;
grid.DataBind();
}
}
}
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Specialized;
using GridTest;
public class GridViewHandler : ITemplate
{
#region data memebers
ListItemType ItemType;
string FieldName;
string InfoType;
string HeaderText;
#endregion
#region constructor
public GridViewHandler(ListItemType item_type, string field_name, string info_type, string header_text)
{
ItemType = item_type;
FieldName = field_name;
InfoType = info_type;
HeaderText = header_text;
}
#endregion
#region Methods
public void InstantiateIn(System.Web.UI.Control Container)
{
switch (ItemType)
{
case ListItemType.Header:
Literal header_ltrl = new Literal();
header_ltrl.Text = "<b>" + HeaderText + "</b>";
Container.Controls.Add(header_ltrl);
break;
case ListItemType.Item:
switch (InfoType)
{
case "CheckBox":
CustomCheckBox check = new CustomCheckBox();
check.ID = "CheckBox";
check.AutoPostBack = true;
//check.CheckedChanged += new EventHandler(checkbox_CheckedChanged);
check.DataBinding += new EventHandler(OnDataBinding);
Container.Controls.Add(check);
break;
case "Command":
ImageButton edit_button = new ImageButton();
edit_button.ID = "edit_button";
edit_button.ImageUrl = "~/images/edit.gif";
edit_button.CommandName = "Edit";
edit_button.Click += new ImageClickEventHandler(edit_button_Click);
edit_button.ToolTip = "Edit";
Container.Controls.Add(edit_button);
ImageButton delete_button = new ImageButton();
delete_button.ID = "delete_button";
delete_button.ImageUrl = "~/images/delete.gif";
delete_button.CommandName = "Delete";
delete_button.ToolTip = "Delete";
delete_button.OnClientClick = "return confirm('Are you sure to delete the record?')";
Container.Controls.Add(delete_button);
/* Similarly add button for insert.
* It is important to know when 'insert' button is added
* its CommandName is set to "Edit" like that of 'edit' button
* only because we want the GridView enter into Edit mode,
* and this time we also want the text boxes for corresponding fields empty*/
ImageButton insert_button = new ImageButton();
insert_button.ID = "insert_button";
insert_button.ImageUrl = "~/images/insert.bmp";
insert_button.CommandName = "Edit";
insert_button.ToolTip = "Insert";
insert_button.Click += new ImageClickEventHandler(insert_button_Click);
Container.Controls.Add(insert_button);
break;
default:
Label field_lbl = new Label();
field_lbl.ID = FieldName;
field_lbl.Text = String.Empty; //we will bind it later through 'OnDataBinding' event
field_lbl.DataBinding += new EventHandler(OnDataBinding);
Container.Controls.Add(field_lbl);
break;
}
break;
case ListItemType.EditItem:
if (InfoType == "Command")
{
ImageButton update_button = new ImageButton();
update_button.ID = "update_button";
update_button.CommandName = "Update";
update_button.ImageUrl = "~/images/update.gif";
if ((int)new Page().Session["InsertFlag"] == 1)
update_button.ToolTip = "Add";
else
update_button.ToolTip = "Update";
update_button.OnClientClick = "return confirm('Are you sure to update the record?')";
Container.Controls.Add(update_button);
ImageButton cancel_button = new ImageButton();
cancel_button.ImageUrl = "~/images/cancel.gif";
cancel_button.ID = "cancel_button";
cancel_button.CommandName = "Cancel";
cancel_button.ToolTip = "Cancel";
Container.Controls.Add(cancel_button);
}
else if (InfoType == "CheckBox")
{
CustomCheckBox check = new CustomCheckBox();
check.ID = "CheckBox";
//check.AutoPostBack = true;
//check.CheckedChanged += new EventHandler(checkbox_CheckedChanged);
check.DataBinding += new EventHandler(OnDataBinding);
Container.Controls.Add(check);
}
else// for other 'non-command' i.e. the key and non key fields, bind textboxes with corresponding field values
{
TextBox field_txtbox = new TextBox();
field_txtbox.ID = FieldName;
field_txtbox.Text = String.Empty;
// if Inert is intended no need to bind it with text..keep them empty
if ((int)new Page().Session["InsertFlag"] == 0)
field_txtbox.DataBinding += new EventHandler(OnDataBinding);
Container.Controls.Add(field_txtbox);
}
break;
}
}
#endregion
#region Event Handlers
public void checkbox_CheckedChanged(object sender, EventArgs e)
{
CustomCheckBox cbox = (CustomCheckBox)sender;
string hej = cbox.ID.ToString();
}
//just sets the insert flag ON so that we ll be able to decide in OnRowUpdating event whether to insert or update
protected void insert_button_Click(Object sender, EventArgs e)
{
new Page().Session["InsertFlag"] = 1;
}
//just sets the insert flag OFF so that we ll be able to decide in OnRowUpdating event whether to insert or update
protected void edit_button_Click(Object sender, EventArgs e)
{
new Page().Session["InsertFlag"] = 0;
}
private void OnDataBinding(object sender, EventArgs e)
{
object bound_value_obj = null;
Control ctrl = (Control)sender;
IDataItemContainer data_item_container = (IDataItemContainer)ctrl.NamingContainer;
int rowid = data_item_container.DataItemIndex;
bound_value_obj = DataBinder.Eval(data_item_container.DataItem, FieldName);
switch (ItemType)
{
case ListItemType.Item:
if (InfoType == "CheckBox")
{
string value = bound_value_obj.ToString();
bool ischecked = false;
if (value.ToLower() == "true")
ischecked = true;
CustomCheckBox cbox = (CustomCheckBox)sender;
cbox.Checked = ischecked;
cbox.RowID = rowid;
cbox.FieldName = FieldName;
cbox.CheckedChanged += new EventHandler(checkbox_CheckedChanged);
}
else
{
Label field_ltrl = (Label)sender;
field_ltrl.Text = bound_value_obj.ToString();
}
break;
case ListItemType.EditItem:
if (InfoType == "CheckBox")
{
string value = bound_value_obj.ToString();
bool ischecked = false;
if (value.ToLower() == "true")
ischecked = true;
CustomCheckBox cbox = (CustomCheckBox)sender;
cbox.Checked = ischecked;
cbox.RowID = rowid;
cbox.FieldName = FieldName;
}
else
{
TextBox field_txtbox = (TextBox)sender;
field_txtbox.Text = bound_value_obj.ToString();
}
break;
}
}
#endregion
}
答案 0 :(得分:1)
您可能希望检查是否确保仅绑定到事件一次。乍一看,似乎你没有检查这个。从您的帖子描述来看,似乎正在发生这种情况。
cbox.CheckedChanged += new EventHandler(checkbox_CheckedChanged);
答案 1 :(得分:1)
我必须承认我没有阅读整个源代码(它非常冗长且格式错误),但根据我的经验,这种类型的行为是由在同一事件触发的代码中附加事件处理程序引起的。因此,对于第一个事件,它将执行正常,第二次有两个事件处理程序,然后是4,依此类推。
编辑:
您可以检查是否已存在这样的事件处理程序:
if (cbox.CheckedChanged==null){
//bind the event handler
}
答案 2 :(得分:1)
如果你不确定在哪里绑定它以确保它只发生一次,你可以在函数开始之前取消绑定它,以确保一次连接最多1个:
例如:
switch (ItemType)
{
case ListItemType.Item:
if (InfoType == "CheckBox")
{
string value = bound_value_obj.ToString();
bool ischecked = false;
if (value.ToLower() == "true")
ischecked = true;
CustomCheckBox cbox = (CustomCheckBox)sender;
cbox.CheckedChanged -= new EventHandler(checkbox_CheckedChanged);
cbox.Checked = ischecked;
cbox.RowID = rowid;
cbox.FieldName = FieldName;
cbox.CheckedChanged += new EventHandler(checkbox_CheckedChanged);
}
else
{
Label field_ltrl = (Label)sender;
field_ltrl.Text = bound_value_obj.ToString();
}
break;