如何在后面的代码中将TemplateField添加到gridview?

时间:2013-12-19 21:36:52

标签: asp.net gridview

我有一个DropDownList,其中包含一个表格列表。在它下面有GridView。根据从下拉列表框中选择的表格,我将动态填充GridView。由于表可能有不同的列名,我需要动态地为GridView创建模板字段。

以下是我的绑定方法。我有两个问题:

  1. 我无法将绑定部分包装在if (!IsPostBack)中,因为根据GridView的选择填充了DropDownList,因此每次更改选择时,列都将被复制
  2. 我没有任何数据,我想我需要设置tField TemplateField的{​​{3}},但我该怎么做?
  3. 我的绑定方法

    private void BindGridView()
    {
        DataSet ds = new DataSet();
    
        try
        {
            ds = …
            if (ds.Tables.Count > 0)
            {
    
                foreach (DataColumn dc in ds.Tables[0].Columns)
                {
                    TemplateField tField = new TemplateField();
                    tField.HeaderText = dc.ColumnName;
                    GridView2.Columns.Add(tField);
                }    
    
                GridView2.DataSource = ds.Tables[0];
                GridView2.DataBind();
            }
            else
            {
                …
            }
        }
        catch (Exception ex)
        {
            …    
        }
    }
    

2 个答案:

答案 0 :(得分:17)

应该注意以下各个步骤:

STEP I :: 创建class inheriting ITemplate interfaceOverride ITemplate界面的方法InstantiateIn()

第二步:

class定义一个constructor,其中ListItemType个对象为parameter

STEP III ::

如果要添加到容器ControlControlCollection必须绑定到某个DataSource列,请注册 OnDataBinding event的处理程序。事件发生时,从数据源检索文本并将其分配给您的控件。例如,hyprLnk_DataBinding事件定义为将数据绑定到ItemTemplate内创建的控件。

public class TemplateGenerator : ITemplate // Class inheriting ITemplate
{
    ListItemType type;
    string columnName;  

    public TemplateGenerator(ListItemType t, string cN)
    {           
       type = t;    
       columnName= cN;    
    }

    // Override InstantiateIn() method
    void ITemplate.InstantiateIn(System.Web.UI.Control container)
    {    
        switch (type)
        {
            case ListItemType.Item:    
               HyperLink hyprLnk = new HyperLink();
               hyprLnk.Target = "_blank"; //Optional.
               hyprLnk.DataBinding+=new EventHandler(hyprLnk_DataBinding);
               container.Controls.Add(hyprLnk);
            break;      
        }
    } 

    // The DataBinding event of your controls
    void hyprLnk_DataBinding(object sender, EventArgs e)
    {    
        HyperLink hyprlnk = (HyperLink)sender;
        GridViewRow container = (GridViewRow)hyprlnk.NamingContainer;
        object bindValue = DataBinder.Eval(container.DataItem,columnName);
        // Adding check in case Column allows null values
        if (bindValue != DBNull.Value) 
        {
            hyprlnk.Text = bindValue.ToString();
            hyprlnk.NavigateUrl = "http://www.google.com";
        }
    }
}

这就是全部。以上只是为GridView动态创建ItemTemplate并为项目模板添加控件的示例。

现在,下面是实际执行动态创建模板列的调用的函数。您可以在需要时调用此功能,例如来自您的DropDownList事件处理程序。

protected void GenerateGridViewColumnsDynamically()
{
    // Create the TemplateField 
    TemplateField firstName = new TemplateField();
    firstName.HeaderText = "First_Name"; 
    firstName.ItemTemplate = new TemplateGenerator(ListItemType.Item, "FirstName");

    // Showing boundField example just for more context
    BoundField lastName = new BoundField();
    lastName.DataField = "LastName";
    lastName.HeaderText = "Last_Name";

    // Add the Columns now
    MyGridView.Columns.Add(firstName);
    MyGridView.Columns.Add(lastName);
}

注意:: FirstName和LastName是Columns,其名称会传递到您的自定义constructor的{​​{1}}:class。< / p>

答案 1 :(得分:0)

我已经完成了与下面相同的功能,自定义分页(使用storedProc)在许多表中有超过100万条记录,也更新,删除和插入:

CREATE PROCEDURE [dbo].[sp_Mk]
    @PageIndex  INT,
    @PageSize INT,
    @tableName nvarchar(255),
    @totalRow INT Output
AS
BEGIN 
DECLARE @sql NVARCHAR(MAX)
Declare @anotherSql NVARCHAR(1000)
DECLARE @ParamDefinition NVARCHAR(500)

--DECLARE @totalRow INT
Set @sql = 'WITH TempResult AS( SELECT *  FROM '+@tableName+'), TempCount AS ( SELECT COUNT(*) AS MaxRows FROM TempResult )
SELECT * FROM TempResult, TempCount ORDER BY (Select Null)
    OFFSET '+CONVERT(VARCHAR(20),(@PageIndex-1)*@PageSize) +' ROWS FETCH NEXT '+CONVERT(VARCHAR(20),@PageSize)+' ROWS ONLY'

PRINT @SQL
EXECUTE sp_executesql @SQL
Set @anotherSql=N'SELECT COUNT(*) as totalRow FROM '+@tableName
SET @ParamDefinition = N'@totalRowOutPut INT  OUTPUT'
--PRINT @anotherSql
Execute sp_executesql @anotherSql, 
@ParamDefinition, 
--@tableNameInput=@tableName, 
@totalRowOutPut=@totalRow OUTPUT
End




<asp:GridView CssClass="table-striped header-fixed" ID="grdDynamic" runat="server" AutoGenerateColumns="True" ShowHeaderWhenEmpty="true" AutoGenerateEditButton="true" AutoGenerateDeleteButton="true" 
            OnRowEditing="OnRowEditing_grdDynamic" OnRowUpdating="OnRowUpdating_grdDynamic" OnRowCancelingEdit="OnRowCancelingEdit_grdDynamic" OnRowDeleting="OnRowDeleting_grdDynamic" OnRowDataBound="OnRowDataBound_grdDynamic">
            </asp:GridView><br/>
            <asp:linkbutton id="AddButton" runat="server" commandname="Add" text="Insert: " OnClick="AddNewButton_Click" /><br/>
            <asp:Repeater ID="rptPager" runat="server">
                <ItemTemplate>
                    <asp:LinkButton ID="lnkPage" CssClass="pagination-ys" runat="server" Text = '<%#Eval("Text") %>' CommandArgument = '<%# Eval("Value") %>' Enabled = '<%# Eval("Enabled") %>' OnClick = "Page_Changed"></asp:LinkButton>
                </ItemTemplate>
            </asp:Repeater><asp:HiddenField runat="server" id="hdnPageIndex" Value="1"></asp:HiddenField>





SqlConnectionStringBuilder builder;
        int pageSize = 100;
        protected void Page_Load(object sender, EventArgs e)
        {
            builder = new SqlConnectionStringBuilder(connectionString);
            if (!IsPostBack)
            {
                using (SqlConnection connObj = new SqlConnection(connectionString))
                {
                    connObj.Open();

                    using (SqlDataAdapter adapter = new SqlDataAdapter("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_CATALOG='" + builder.InitialCatalog + "' AND TABLE_NAME Not In('AspNetUsers') Order By TABLE_NAME", connObj))
                    {
                        DataSet ds = new DataSet();
                        adapter.Fill(ds);
                        ddlTableNames.DataSource = ds;
                        ddlTableNames.DataBind();
                        ddlTableNames.Items.Insert(0, new ListItem("Select Table", String.Empty));
                    }
                }
            }
            //}
            //else if(ddlTableNames.Visible) ddlTableNames.Visible = false;
        }

        protected void ddlTableNames_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (ddlTableNames.SelectedValue != "")
            {
                grdDynamic.Visible = true;
                this.BindGrid(ddlTableNames.SelectedValue, Convert.ToInt32(hdnPageIndex.Value));
            }
            else if (grdDynamic.Visible == true) grdDynamic.Visible = false;
        }

        private void BindGrid(string selectedTable, int pageIndex, bool addNewRow=false)
        {
            using (SqlConnection connObj = new SqlConnection(connectionString))
            {
                using (SqlCommand cmd = new SqlCommand("sp_Mk", connObj))
                {
                    int recordCount=0;
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@PageIndex", pageIndex);
                    cmd.Parameters.AddWithValue("@PageSize", pageSize);
                    cmd.Parameters.AddWithValue("@tableName", ddlTableNames.SelectedValue);
                    SqlParameter totalRow = new SqlParameter("@totalRow", SqlDbType.Int, 4);
                    totalRow.Direction = ParameterDirection.Output;
                    cmd.Parameters.Add(totalRow);
                    connObj.Open();
                    SqlDataAdapter adapter = new SqlDataAdapter(cmd);
                    DataSet ds = new DataSet();
                    adapter.Fill(ds);
                    grdDynamic.DataSource = ds.Tables[0];
                    if (addNewRow) ds.Tables[0].Rows.Add();
                    recordCount = Convert.ToInt32(ds.Tables[1].Rows[0].ItemArray[0]);
                    grdDynamic.DataBind();

                    connObj.Close();
                    if (totalRow.Value != DBNull.Value)
                    {

                    }
                    this.PopulatePager(recordCount, pageIndex);
                }
            }
        }

        private void PopulatePager(int recordCount, int currentPage)
        {
            double dblPageCount = (double)((decimal)recordCount / pageSize);
            int pageCount = (int)Math.Ceiling(dblPageCount);
            List<ListItem> pages = new List<ListItem>();
            if (pageCount > 0)
            {
                pages.Add(new ListItem("First", "1", currentPage > 1));
                for (int i = 1; i <= pageCount; i++)
                {
                    ListItem item=new ListItem(i.ToString(), i.ToString(), i != currentPage);
                    if (i == currentPage) item.Attributes.Add("style", "color:red;");
                    pages.Add(item);
                }
                pages.Add(new ListItem("Last", pageCount.ToString(), currentPage < pageCount));
            }
            rptPager.DataSource = pages;
            rptPager.DataBind();
        }

        protected void Page_Changed(object sender, EventArgs e)
        {
            int pageIndex = int.Parse((sender as LinkButton).CommandArgument);
            hdnPageIndex.Value = pageIndex.ToString();
            this.BindGrid(ddlTableNames.SelectedValue, pageIndex);
        }

        protected void OnRowEditing_grdDynamic(object sender, GridViewEditEventArgs e)
        {
            grdDynamic.EditIndex = e.NewEditIndex;
            this.BindGrid(ddlTableNames.SelectedValue, Convert.ToInt32(hdnPageIndex.Value));
        }

        protected void OnRowUpdating_grdDynamic(object sender, GridViewUpdateEventArgs e)
        {
            GridViewRow row = grdDynamic.Rows[e.RowIndex];
            string updateStatement = string.Empty;
            for (int x = 0; x < row.Cells.Count; x++) updateStatement = updateStatement + grdDynamic.DataKeys[e.RowIndex].Values[x] + " = " + grdDynamic.DataKeys[e.RowIndex].Values[x] + ", ";
            //int recordId = Convert.ToInt32(grdDynamic.DataKeys[e.RowIndex].Values[0]);
            using (SqlConnection con = new SqlConnection(connectionString))
            {
                //using (SqlCommand cmd = new SqlCommand("UPDATE "+selectedTable"+ SET Name = @Name, Country = @Country WHERE CustomerId = @CustomerId"))
                {
                    cmd.Connection = con;
                    con.Open();
                    cmd.ExecuteNonQuery();
                    con.Close();
                }
            }
            grdDynamic.EditIndex = -1;
            this.BindGrid(ddlTableNames.SelectedValue, Convert.ToInt32(hdnPageIndex.Value));
        }

        protected void OnRowCancelingEdit_grdDynamic(object sender, EventArgs e)
        {
            grdDynamic.EditIndex = -1;
            this.BindGrid(ddlTableNames.SelectedValue, Convert.ToInt32(hdnPageIndex.Value));
        }

        protected void OnRowDeleting_grdDynamic(object sender, GridViewDeleteEventArgs e)
        {
            int recordId = Convert.ToInt32(grdDynamic.DataKeys[e.RowIndex].Values[0]);
            using (SqlConnection con = new SqlConnection(connectionString))
            {
                using (SqlCommand cmd = new SqlCommand("DELETE FROM " + ddlTableNames.SelectedValue + " WHERE RecordId = @recordId"))
                {
                    cmd.Connection = con;
                    con.Open();
                    cmd.ExecuteNonQuery();
                    con.Close();
                }
            }
            this.BindGrid(ddlTableNames.SelectedValue, Convert.ToInt32(hdnPageIndex.Value));
        }

        protected void btnGo_Click(object sender, EventArgs e)
        {   int myInt;
            if(txtPageSize.Text!=null && txtPageSize.Text !=string.Empty)
                if(int.TryParse(txtPageSize.Text, out myInt)) pageSize = myInt;
            hdnPageIndex.Value = "1";
            this.BindGrid(ddlTableNames.SelectedValue, 1);
        }

        protected void AddNewButton_Click(object sender, EventArgs e)
        {
            hdnPageIndex.Value="1";
            this.BindGrid(ddlTableNames.SelectedValue, Convert.ToInt32(hdnPageIndex.Value), true);
        }

        protected void OnRowDataBound_grdDynamic(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow && e.Row.RowIndex != grdDynamic.EditIndex)
            {
                (e.Row.Cells[0].Controls[2] as LinkButton).Attributes["onclick"] = "return confirm('Do you want to delete this row?');";
            }
        }

希望有所帮助: