[英]Dynamic generation of CheckBox in asp.net gridview does not maintain the state
[英]Dynamic GridView generation
我可能会在这里离开我的联盟,但在过去的几天里我尝试设计最终的动态网格视图生成机制。然后我就陷入了困境。 :)
那么,为何终极?
好吧,我有2个表格,我在应用程序中映射每个类似列表(命名法)的表格(例如:人员类型,地址类型,客户端类型,县,国家等)。
我想创建一种机制,将每个表动态地生成到包含所有CRUD功能的网格视图中,而不是为每个表和其中一个表创建网格视图。 这意味着我需要EditItemTemplate和FooterTemplate才能工作。
这里:这个机制的底层“配置”表:
CREATE TABLE EXP_LIST_COLUMN_TYPE
(
COLUMN_TYPE_ID INT IDENTITY(1,1) NOT NULL CONSTRAINT IDX_PK_COLUMN_TYPE_ID PRIMARY KEY CLUSTERED,
COLUMN_TYPE NVARCHAR(255) NOT NULL
)
GO
CREATE TABLE EXP_LIST_HEADER
(
LIST_HEADER_ID INT IDENTITY(1,1) NOT NULL CONSTRAINT IDX_PK_LIST_HEADER_ID PRIMARY KEY CLUSTERED,
DISPLAY_NAME NVARCHAR(255) NOT NULL,
TABLE_NAME NVARCHAR(255) NOT NULL,
TABLE_PRIMARY_KEY NVARCHAR(255) NOT NULL,
ACTIVE INT NOT NULL
)
GO
CREATE TABLE EXP_LIST_DETAILS
(
LIST_DETAIL_ID INT IDENTITY(1,1) NOT NULL CONSTRAINT IDX_PK_LIST_DETAIL_ID PRIMARY KEY CLUSTERED,
LIST_HEADER_ID INT NOT NULL CONSTRAINT FK_LIST_HEADER_ID FOREIGN KEY REFERENCES EXP_LIST_HEADER(LIST_HEADER_ID),
DISPLAY_COLUMN_NAME NVARCHAR(255) NOT NULL,
DISPLAY_COLUMN_TYPE_ID INT NOT NULL CONSTRAINT FK_COL_TYPE_ID FOREIGN KEY REFERENCES EXP_LIST_COLUMN_TYPE(COLUMN_TYPE_ID),
DISPLAY_COLUMN_LENGTH INT NOT NULL,
VISIBLE INT NOT NULL,
DDL_LIST_DETAIL_ID INT NULL CONSTRAINT DDL_LIST_DETAIL_ID FOREIGN KEY REFERENCES EXP_LIST_DETAILS(LIST_DETAIL_ID),
COLUMN_NAME NVARCHAR(255) NOT NULL
)
GO
INSERT INTO EXP_LIST_COLUMN_TYPE
(COLUMN_TYPE)
SELECT 'Date'
UNION ALL
SELECT 'TextBox'
UNION ALL
SELECT 'Label'
UNION ALL
SELECT 'CheckBox'
UNION ALL
SELECT 'DropDownList'
GO
INSERT INTO EXP_LIST_HEADER
(DISPLAY_NAME,TABLE_NAME,TABLE_PRIMARY_KEY,ACTIVE)
SELECT 'Person Types','PERSON_TYPE','PERSON_TYPE_ID',1
UNION ALL
SELECT 'Address Types','ADDRESS_TYPES','ADDRESS_TYPE_ID',1
UNION ALL
SELECT 'Countries','COUNTRY','COUNTRY_ID',1
UNION ALL
SELECT 'Counties','COUNTY','COUNTY_ID',1
GO
INSERT INTO EXP_LIST_DETAILS
(
LIST_HEADER_ID,
DISPLAY_COLUMN_NAME,
DISPLAY_COLUMN_TYPE_ID,
DISPLAY_COLUMN_LENGTH,
VISIBLE,
DDL_LIST_DETAIL_ID,
COLUMN_NAME
)
SELECT 1,'Person Type',2,255,1,NULL,'TYPENAME'
UNION ALL
SELECT 2,'Address Type',2,255,1,NULL,'ADDRESS_TYPE'
UNION ALL
SELECT 3,'Country Code',2,3,1,NULL,'CODE'
UNION ALL
SELECT 3,'Country Name',2,255,1,NULL,'NAME'
UNION ALL
SELECT 4,'County Code',2,3,1,NULL,'CODE'
UNION ALL
SELECT 4,'County Name',2,255,1,NULL,'NAME'
UNION ALL
SELECT 4,'Country',5,3,1,3,'COUNTRY_ID'
GO
和2个存储过程将输出标题和细节,如下所示:
--GET LIST HEADER
IF OBJECT_ID(N'USP_GET_LIST_HEADER','P') IS NOT NULL
DROP PROCEDURE USP_GET_LIST_HEADER
GO
CREATE PROCEDURE USP_GET_LIST_HEADER @LIST_HEADER_ID INT
AS
BEGIN
SELECT DISTINCT
H.LIST_HEADER_ID
, H.DISPLAY_NAME
, H.TABLE_NAME
, H.TABLE_PRIMARY_KEY
FROM EXP_LIST_HEADER H
JOIN EXP_LIST_DETAILS D ON D.LIST_HEADER_ID = H.LIST_HEADER_ID
WHERE
H.LIST_HEADER_ID = @LIST_HEADER_ID
AND H.ACTIVE = 1
END
GO
--GET LIST DETAILS
IF OBJECT_ID(N'USP_GET_LIST_DETAILS','P') IS NOT NULL
DROP PROCEDURE USP_GET_LIST_DETAILS
GO
CREATE PROCEDURE USP_GET_LIST_DETAILS @LIST_HEADER_ID INT
AS
BEGIN
SELECT
D.LIST_DETAIL_ID
, D.DISPLAY_COLUMN_NAME
, D.VISIBLE
, CT.COLUMN_TYPE
, D.DISPLAY_COLUMN_LENGTH
, DDLH.TABLE_NAME + '.' + DDLH.TABLE_PRIMARY_KEY AS DDL_VALUE
, DDLH.TABLE_NAME + '.' + DDLD.COLUMN_NAME AS DDL_TEXT
, DDLH.TABLE_NAME AS DDL_TABLE
, D.COLUMN_NAME
FROM EXP_LIST_HEADER H
JOIN EXP_LIST_DETAILS D ON D.LIST_HEADER_ID = H.LIST_HEADER_ID
JOIN EXP_LIST_COLUMN_TYPE CT ON CT.COLUMN_TYPE_ID = D.DISPLAY_COLUMN_TYPE_ID
LEFT JOIN EXP_LIST_DETAILS DDLD ON DDLD.LIST_DETAIL_ID = D.DDL_LIST_DETAIL_ID
LEFT JOIN EXP_LIST_HEADER DDLH ON DDLH.LIST_HEADER_ID = DDLD.LIST_HEADER_ID
WHERE
H.LIST_HEADER_ID = @LIST_HEADER_ID
AND H.ACTIVE = 1
END
GO
这两个sp将给我一个gridview的结构:
EXEC USP_GET_LIST_HEADER 4
EXEC USP_GET_LIST_DETAILS 4
鉴于此,我有一个Web表单,其中我有一个下拉列表,用户从中选择要管理的列表,并根据用户的选择,将根据基础数据动态生成gridview:
<asp:DropDownList ID="ddlLists" runat="server" DataSourceID="dsLists"
DataTextField="LIST_NAME" DataValueField="LIST_HEADER_ID" Width="100%"
Font-Bold="true" AutoPostBack="true"
onselectedindexchanged="ddlLists_SelectedIndexChanged" >
</asp:DropDownList>
<asp:UpdateProgress runat="server" ID="updpgrDynamicList" AssociatedUpdatePanelID="updpanDynamicList">
<ProgressTemplate>
<img src="../Images/ajax-loader.gif" alt="Please wait..." />
</ProgressTemplate>
</asp:UpdateProgress>
<asp:UpdatePanel runat="server" ID="updpanDynamicList" UpdateMode="Conditional">
<ContentTemplate>
<asp:GridView ID="gvDynamicList" runat="server"
Visible="true" ShowFooter="true"
AllowPaging="True" PageSize="5" PagerStyle-Mode="NumericPages"
PagerStyle-HorizontalAlign="Center" PagerStyle-NextPageText="Next" PagerStyle-PrevPageText="Prev"
BorderWidth="0" GridLines="Both" CellPadding="1" CellSpacing="0"
Font-Name="Verdana" Font-Size="7pt" ShowHeaderWhenEmpty="true"
HeaderStyle-BackColor="#aaaadd" AlternatingItemStyle-BackColor="#eeeeee"
AutoGenerateColumns="false"
onpageindexchanging="gvDynamicList_PageIndexChanging"
onrowcancelingedit="gvDynamicList_RowCancelingEdit"
onrowcommand="gvDynamicList_RowCommand"
onrowdeleting="gvDynamicList_RowDeleting"
onrowediting="gvDynamicList_RowEditing"
onrowupdating="gvDynamicList_RowUpdating"
>
<EmptyDataRowStyle HorizontalAlign="Center" BackColor="Red" Font-Bold="true"/>
<FooterStyle BackColor="#ececff" />
<HeaderStyle BackColor="#30308f" Font-Bold="True" ForeColor="White" Font-Size="7pt" HorizontalAlign="Center"/>
<Columns>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
<br />
<asp:Label ID="lblError" runat="server" Text="" ForeColor="Red" Font-Bold="true"></asp:Label>
<asp:SqlDataSource ID="dsLists" runat="server" ConnectionString="<%$ ConnectionStrings:LocalSqlServer %>"
SelectCommand="SELECT LIST_HEADER_ID, DISPLAY_NAME AS LIST_NAME FROM EXP_LIST_HEADER WHERE ACTIVE=1 UNION ALL SELECT -1,'' ORDER BY 1 ASC">
</asp:SqlDataSource>
代码隐藏:
protected void ddlLists_SelectedIndexChanged(object sender, EventArgs e)
{
int ListHeaderId;
Int32.TryParse(ddlLists.SelectedItem.Value.ToString(), out ListHeaderId);
if (ListHeaderId != 0)
{
try
{
PopulateDynamicGridView(ListHeaderId);
}
catch (Exception ex)
{
lblError.Text = "Error: " + ex.Message;
}
}
}
protected void PopulateDynamicGridView(int ListHeaderId)
{
gvDynamicList.Columns.Clear();
gvDynamicList.DataBind();
using (SqlConnection sqlConn = new SqlConnection(WebConfigurationManager.ConnectionStrings["LocalSqlServer"].ConnectionString))
{
SqlCommand sqlGetListHeader = new SqlCommand(@"EXEC USP_GET_LIST_HEADER @LIST_HEADER_ID", sqlConn);
sqlGetListHeader.Parameters.Add("@LIST_HEADER_ID", SqlDbType.Int);
sqlGetListHeader.Parameters["@LIST_HEADER_ID"].Value = ListHeaderId;
SqlDataAdapter daListHeader = new SqlDataAdapter(sqlGetListHeader);
DataTable dtListHeader = new DataTable("LIST_HEADER");
SqlCommand sqlGetListDetails = new SqlCommand(@"EXEC USP_GET_LIST_DETAILS @LIST_HEADER_ID", sqlConn);
sqlGetListDetails.Parameters.Add("@LIST_HEADER_ID", SqlDbType.Int);
sqlGetListDetails.Parameters["@LIST_HEADER_ID"].Value = ListHeaderId;
SqlDataAdapter daListDetails = new SqlDataAdapter(sqlGetListDetails);
DataTable dtListDetails = new DataTable("LIST_DETAILS");
try
{
sqlConn.Open();
daListHeader.Fill(dtListHeader);
if (dtListHeader.Rows.Count == 1)
{
daListDetails.Fill(dtListDetails);
if (dtListDetails.Rows.Count >= 1)
{
string sqlDynamicCommand = "SELECT " + dtListHeader.Rows[0]["TABLE_PRIMARY_KEY"].ToString() + ", ";
//add the primary key of the underlying table as a bound field to the gv
//useful later in edit mode
BoundField bfGVPk = new BoundField();
bfGVPk.DataField = dtListHeader.Rows[0]["TABLE_PRIMARY_KEY"].ToString();
bfGVPk.ReadOnly = true;
bfGVPk.HeaderText = dtListHeader.Rows[0]["TABLE_PRIMARY_KEY"].ToString();
bfGVPk.Visible = false;
gvDynamicList.Columns.Add(bfGVPk);
foreach(DataRow drDetails in dtListDetails.Rows)
{
string DisplayColumnName = drDetails["DISPLAY_COLUMN_NAME"].ToString();
int Visible = Convert.ToInt32(drDetails["VISIBLE"].ToString());
string ColumnType = drDetails["COLUMN_TYPE"].ToString();
int ColumnLength = Convert.ToInt32(drDetails["DISPLAY_COLUMN_LENGTH"].ToString());
string DDLValue = drDetails["DDL_VALUE"].ToString();
string DDLText = drDetails["DDL_TEXT"].ToString();
string DDLTable = drDetails["DDL_TABLE"].ToString();
string ColumnName = drDetails["COLUMN_NAME"].ToString();
if (ColumnType != "DropDownList")
{
TemplateField tmplfield = new TemplateField();
tmplfield.HeaderTemplate = new GridViewTemplate(ListItemType.Header, DisplayColumnName, Visible);
tmplfield.ItemTemplate = new GridViewTemplate(ListItemType.Item, ColumnName,"Label");
tmplfield.EditItemTemplate = new GridViewTemplate(ListItemType.EditItem, DisplayColumnName, ColumnName, ColumnType, Visible, ColumnLength);
tmplfield.FooterTemplate = new GridViewTemplate(ListItemType.Footer, DisplayColumnName, ColumnName, ColumnType, Visible, ColumnLength);
gvDynamicList.Columns.Add(tmplfield);
}
sqlDynamicCommand += ColumnName + ",";
}
//add the edit column
TemplateField tmplfieldEdit = new TemplateField();
tmplfieldEdit.HeaderTemplate = new GridViewTemplate(ListItemType.Header, "Edit", 1);
tmplfieldEdit.ItemTemplate = new GridViewTemplate(ListItemType.Item, "Edit", "ImageButton");
tmplfieldEdit.EditItemTemplate = new GridViewTemplate(ListItemType.EditItem, "", "", "ImageButton", 1, 0);
tmplfieldEdit.FooterTemplate = new GridViewTemplate(ListItemType.Footer, "", "", "ImageButton", 1, 0);
gvDynamicList.Columns.Add(tmplfieldEdit);
//add the delete column
TemplateField tmplfieldDelete = new TemplateField();
tmplfieldDelete.HeaderTemplate = new GridViewTemplate(ListItemType.Header, "Delete", 1);
tmplfieldDelete.ItemTemplate = new GridViewTemplate(ListItemType.Item, "Delete", "ImageButton");
gvDynamicList.Columns.Add(tmplfieldDelete);
//removing the final comma
sqlDynamicCommand = sqlDynamicCommand.Substring(0, sqlDynamicCommand.Length - 1);
//adding the table
sqlDynamicCommand += " FROM " + dtListHeader.Rows[0]["TABLE_NAME"].ToString();
using (SqlConnection sqlConnDynamicDS = new SqlConnection(WebConfigurationManager.ConnectionStrings["LocalSqlServer"].ConnectionString))
{
SqlCommand sqlGetDynamicDataSource = new SqlCommand(sqlDynamicCommand, sqlConnDynamicDS);
SqlDataAdapter daDynamic = new SqlDataAdapter(sqlGetDynamicDataSource);
DataTable dtDynamic = new DataTable("DYNAMIC_DATA_SOURCE");
daDynamic.Fill(dtDynamic);
gvDynamicList.DataSource = dtDynamic;
gvDynamicList.DataBind();
}
}
}
}
catch (Exception ex)
{
throw ex;
}
}
}
我的ITemplate的实现:
public class GridViewTemplate : System.Web.UI.Page, ITemplate
{
ListItemType _templateType;
string _columnName;
string _controlType;
int _visible;
int _columnLength;
string _displayColumnName;
//Header constructor
public GridViewTemplate(ListItemType type, string displaycolumnname,int visible)
{
_templateType = type;
_displayColumnName = displaycolumnname;
_visible = visible;
}
//Item constructor
public GridViewTemplate(ListItemType type, string columnname, string controlType)
{
_templateType = type;
_columnName = columnname;
_controlType = controlType;
}
//EditItem and Footer constructor
public GridViewTemplate(ListItemType type,string displaycolumnname, string colname, string controltype, int visible, int columnlength)
{
_templateType = type;
_columnName = colname;
_controlType = controltype;
_visible = visible;
_columnLength = columnlength;
_displayColumnName = displaycolumnname;
}
void ITemplate.InstantiateIn(System.Web.UI.Control container)
{
switch (_templateType)
{
case ListItemType.Header:
try
{
//Headers will always be labels
Label lblHeader = new Label();
lblHeader.Text = _displayColumnName;
if (_visible != 1)
{
lblHeader.Visible = false;
}
container.Controls.Add(lblHeader);
}
catch (Exception ex)
{
throw ex;
}
break;
case ListItemType.Item:
try
{
//Items can be only Labels or ImageButtons
if (_controlType == "Label")
{
Label lblItem = new Label();
lblItem.ID = "lbl" + _columnName;
lblItem.Text = String.Empty;
lblItem.DataBinding += new EventHandler(OnDataBinding);
container.Controls.Add(lblItem);
}
if (_controlType == "ImageButton" && _columnName == "Edit")
{
ImageButton imgbtnItem = new ImageButton();
imgbtnItem.ID = "img_btnEdit";
imgbtnItem.CommandName = "Edit";
imgbtnItem.ImageUrl = "~/Images/document_edit.png";
imgbtnItem.AlternateText = _columnName;
imgbtnItem.CausesValidation = false;
imgbtnItem.Click += new ImageClickEventHandler(imgbtnItem_Edit);
container.Controls.Add(imgbtnItem);
}
if (_controlType == "ImageButton" && _columnName == "Delete")
{
ImageButton imgbtnItem = new ImageButton();
imgbtnItem.ID = "btnDelete";
imgbtnItem.CommandName = "Delete";
imgbtnItem.ImageUrl = "~/Images/document_delete.png";
imgbtnItem.AlternateText = _columnName;
imgbtnItem.CausesValidation = false;
imgbtnItem.OnClientClick = "return confirm('Are you sure you want to delete this record?')";
container.Controls.Add(imgbtnItem);
}
}
catch (Exception ex)
{
throw ex;
}
break;
case ListItemType.EditItem:
try
{
if (_controlType == "TextBox")
{
TextBox tbEditItem = new TextBox();
tbEditItem.ID = "tbEdit" + _columnName;
tbEditItem.Text = String.Empty;
tbEditItem.DataBinding += new EventHandler(OnDataBinding);
tbEditItem.MaxLength = _columnLength;
}
if (_controlType == "Label")
{
//Labels will basically render the control in a ReadOnly state
Label lblEditItem = new Label();
lblEditItem.ID = "lblEditItem" + _columnName;
lblEditItem.Text = String.Empty;
lblEditItem.DataBinding += new EventHandler(OnDataBinding);
}
if (_controlType == "Date")
{
TextBox tbDateEditItem = new TextBox();
tbDateEditItem.ID = "tbDateEdit" + _columnName;
tbDateEditItem.Text = String.Empty;
tbDateEditItem.MaxLength = _columnLength;
tbDateEditItem.DataBinding += new EventHandler(OnDataBinding);
AjaxControlToolkit.CalendarExtender ajCe = new AjaxControlToolkit.CalendarExtender();
ajCe.ID = "ceEdit" + _columnName;
ajCe.Format = "dd.MM.yyyy";
ajCe.TargetControlID = tbDateEditItem.ID;
}
if (_controlType == "DropDownList")
{
//work in progress :)
}
//Here we will add 2 ImageButtons inside the EditItemTemplate
//One will be to Save the edited date
//The other one will close the edit mode of the gridview (Cancel)
if (_controlType == "ImageButton")
{
ImageButton imgbtnEditItemSave = new ImageButton();
imgbtnEditItemSave.ID = "img_btnSave";
imgbtnEditItemSave.CommandName = "Update";
imgbtnEditItemSave.ImageUrl = "~/Images/document_save.png";
imgbtnEditItemSave.AlternateText = "Save";
imgbtnEditItemSave.CausesValidation = true;
imgbtnEditItemSave.ValidationGroup = "SaveRow"; //in case a validation is defined on any other EditItems
ImageButton imgbtnEditItemEditClose = new ImageButton();
imgbtnEditItemEditClose.ID = "img_btnCancel";
imgbtnEditItemEditClose.CommandName = "Cancel";
imgbtnEditItemEditClose.ImageUrl = "~/Images/document_cancel.png";
imgbtnEditItemEditClose.AlternateText = "Cancel";
imgbtnEditItemEditClose.CausesValidation = false;
}
}
catch (Exception ex)
{
throw ex;
}
break;
case ListItemType.Footer:
if (_controlType == "TextBox")
{
TextBox tbNewItem = new TextBox();
tbNewItem.ID = "tbNew" + _columnName;
tbNewItem.Text = String.Empty;
tbNewItem.MaxLength = _columnLength;
}
if (_controlType == "ImageButton")
{
ImageButton imgbtnAddNewItem = new ImageButton();
imgbtnAddNewItem.ID = "img_btnInsert";
imgbtnAddNewItem.CommandName = "AddNew";
imgbtnAddNewItem.ImageUrl = "~/Images/document_insert.png";
imgbtnAddNewItem.AlternateText = "Insert";
imgbtnAddNewItem.CausesValidation = true;
imgbtnAddNewItem.ValidationGroup = "AddRow";
}
if (_controlType == "DropDownList")
{
//work in progress :)
}
if (_controlType == "CheckBox")
{
//work in progress :)
}
if (_controlType == "Date")
{
TextBox tbNewItem = new TextBox();
tbNewItem.ID = "tbNew" + _columnName;
tbNewItem.Text = String.Empty;
tbNewItem.MaxLength = _columnLength;
AjaxControlToolkit.CalendarExtender ajCe = new AjaxControlToolkit.CalendarExtender();
ajCe.ID = "ceEdit" + _columnName;
ajCe.Format = "dd.MM.yyyy";
ajCe.TargetControlID = tbNewItem.ID;
}
break;
}
}
protected void imgbtnItem_Edit(object sender, ImageClickEventArgs e)
{
}
private void OnDataBinding(object sender, EventArgs e)
{
object bound_value_obj = null;
Control ctrl = (Control)sender;
IDataItemContainer data_item_container = (IDataItemContainer)ctrl.NamingContainer;
bound_value_obj = DataBinder.Eval(data_item_container.DataItem, _columnName);
switch (_templateType)
{
case ListItemType.Item:
Label field_ltrl = (Label)sender;
field_ltrl.Text = bound_value_obj.ToString();
break;
case ListItemType.EditItem:
TextBox field_txtbox = (TextBox)sender;
field_txtbox.Text = bound_value_obj.ToString();
break;
}
}
}
当我运行表单时,Header和Item模板似乎不错,但我在页脚中没有任何内容。 我应该在这里有2个文本框和一个ImageButton
,但我没有:
此外,当我按下任何行的编辑图像按钮时,这就是我得到的:
从我注意到,在编辑模式下,当ListItemType
是EditItem
时,它永远不会触发OnDataBinding
事件。
我知道这里有很多代码需要消化,但是如果我能够将其发挥作用,我将发布整个代码,以便每个人都能从中受益,如果他们觉得有趣的话。
任何想法都会受到欢迎!!
寻找Edit Index
并找到编辑按钮单击RowCommand
我希望它能帮到你。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.