Как добавить TemplateField в gridview в коде позади?

У меня есть выпадающий список, в котором есть список таблиц. Под ним находится GridView. На основе таблицы, выбранной из выпадающего списка, я буду заполнять GridView динамически. Поскольку таблицы могут иметь разные имена столбцов, мне нужно создать поле шаблона для GridView динамически. Ниже приведена моя функция bind. У меня две проблемы. (1) я не мог обернуть связующую часть в If (!IsPostBack), так как GridView заполняется на основе выбора раскрывающегося списка список, поэтому каждый раз, когда я изменяю выбор, столбцы будут дублироваться (2) и у меня нет никаких данных, я думаю, что мне нужно установить ItemTemplate tField (TemplateField), но как это сделать?

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 ответов


существуют различные шаги, о которых следует позаботиться:

ШАГ I:: Создайте класс, наследующий ITemplate интерфейс. Перезаписать функцию InstantiateIn() на ITemplate интерфейс.

ШАГ II:

определите конструктор для вашего класса, который принимает ListItemType объект как параметр.

ШАГ III::

если элемент управления, добавляемый в коллекцию controls контейнера имеет чтобы быть привязанным к некоторому столбцу источника данных, зарегистрируйте обработчик OnDataBinding событие. При возникновении события извлеките текст из источника данных и присвоить его контроля. Например,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";
        }
     }

вот и все. Выше был только образец для create ItemTemplate динамически для GridView и добавьте элементы управления в шаблон элемента.

теперь Ниже приведена функция, которая фактически будет выполнять вызовы для динамического создания столбцов шаблона. Вы можете вызвать эту функцию, когда это необходимо, например, из обработчика событий 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-это столбцы, имена которых передаются конструктору пользовательского класса: TemplateGenerator


Я сделал ту же функциональность, что и ниже, с пользовательской подкачкой (используя 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?');";
            }
        }

надеюсь, это поможет: