BulkEditGridView [英] BulkEditGridView

查看:139
本文介绍了BulkEditGridView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在解决我的学术项目中的一个问题时,我需要一种帮助,我们将不胜感激.我碰到了一个无法解决的问题.

我将关注点分离到POC程序中,问题的描述如下:

我在运行时建立数据表,即没有行的动态列,然后由于需要不同的控件,因此通过templatefields将列从数据表绑定到gridview.因为我需要gridview中的一项功能,所以每当添加新行时都应该是编辑模式,所以我使用了自定义grideview做到这一点.现在绑定列后如果我添加或修改包含gridview textchange事件的问题没有发生,因此dirtyrow集合为空.您能帮我解决这个问题吗?我在自定义gridview和aspx.cs文件的代码下面添加了.请帮助我.

POCGrideview.aspx.cs

i need to one help in solving one issue in my academic project a help will be appreciated. I struck in the one area not able to solve.

I have seperated the concern in POC program, Description of the problem is as follows:

Im building the datatable at runtime i.e dynamic columns without rows then binding columns from the datatable to gridview through templatefields as i need different controls.since i need a feature in the gridview that whenever new row is added it should be edit mode i used customized grideview which does this. now the problem after bindng the column if i add or modify the contain the gridview textchange event is not occuring hence dirtyrow collection is empty. Can you help me in solving this i have added below the code for custom gridview and my aspx.cs file.please help me.

POCGrideview.aspx.cs

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;

public partial class POCGridView : System.Web.UI.Page
{
DataTable dt = new DataTable();

/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Page_Load(object sender, EventArgs e)
{

    if (!IsPostBack)
    {
        //build the datatable
        dt = BuildDataTable();
        //adding data to table
        InsertTableData(dt, 1, "Sameer");
        InsertTableData(dt, 2, "Ahmed");
        Session["Table"] = dt;

        BindTableToGrid();
    }
}

/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>

protected void CreateButton_Click(object sender, EventArgs e)
{
    //bind the template field
    BindTableToGrid();

}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>

protected void AddRowButton_Click(object sender, EventArgs e)
{
    //Add the data to Grid
    AddRow();
}
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>

protected void SaveDataButton_Click(object sender, EventArgs e)
{
    //Save the data
    SaveData();
}

/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void DeleteRowButton_Click(object sender, EventArgs e)
{
    //DeleteDataTableRows
    DeleteData();

}

#region helper functions
/// <summary>
///
/// </summary>
/// <param name="dt"></param>
/// <param name="RowId"></param>
/// <param name="strData"></param>
private void InsertTableData(DataTable dt, int RowId, String strData)
{
    DataRow dr = dt.NewRow();
    dr["RowId"] = RowId;
    dr["Data"] = strData;
    dt.Rows.Add(dr);
}
/// <summary>
///
/// </summary>
/// <returns></returns>
private DataTable BuildDataTable()
{
    DataTable dt = new DataTable();
    dt.Columns.Add("RowId", Type.GetType("System.Int32"));
    dt.Columns.Add("Data", Type.GetType("System.String"));
    return dt;
}

/// <summary>
///
/// </summary>
private void AddTemplateFieldsToGrid()
{
    if (Session["Table"] != null)
    {
        DataTable dt = Session["Table"] as DataTable;
        foreach (DataColumn col in dt.Columns)
        {
            TemplateField tmpField = new TemplateField();
            tmpField.HeaderTemplate = new MyTemplateClass(ListItemType.Header, col.ColumnName);
            tmpField.EditItemTemplate = new MyTemplateClass(ListItemType.EditItem, col.ColumnName);
            BulkEditGridView1.Columns.Add(tmpField);
        }
    }
}

/// <summary>
///
/// </summary>
private void BindTableToGrid()
{
    if (Session["Table"] != null)
    {
        DataTable dt = Session["Table"] as DataTable;
        AddTemplateFieldsToGrid();
        BulkEditGridView1.DataSource = dt;
        BulkEditGridView1.DataBind();

    }
}
/// <summary>
///
/// </summary>
private void AddRow()
{
    if (Session["Table"] != null)
    {
        DataTable dt = Session["Table"] as DataTable;
        DataRow dr = dt.NewRow();
        dt.Rows.Add(dr);
        Session["Table"] = dt;
    }
    BindTableToGrid();

}
/// <summary>
///
/// </summary>
private void SaveData()
{
    if (Session["Table"] != null)
    {
        DataTable dt = Session["Table"] as DataTable;
        dt.WriteXml("Data.xml");
    }
}
/// <summary>
///
/// </summary>
private void DeleteData()
{
    if (Session["Table"] != null)
    {
        DataTable dt = Session["Table"] as DataTable;
        dt.Rows.Clear();
        Session["Table"] = dt;
    }
}
#endregion

protected class MyTemplateClass : ITemplate
{
    private string ColumnName;
    private ListItemType Item;

    public MyTemplateClass(ListItemType item, string columnName)
    {
        Item = item;
        ColumnName = columnName;
    }


    #region ITemplate Members

    public void InstantiateIn(Control container)
    {
        switch (Item)
        {
            case ListItemType.Header:
                Label lbl = new Label();
                lbl.Text = ColumnName;
                container.Controls.Add(lbl);
                break;
            case ListItemType.EditItem:
                TextBox txt = new TextBox();
                txt.DataBinding += new EventHandler(txt_DataBinding);
                txt.TextChanged += new EventHandler(txt_TextChanged);
                txt.AutoPostBack = true;
                txt.Columns = 3;
                container.Controls.Add(txt);
                break;
            case ListItemType.Footer:
                break;
        }
    }

    void txt_TextChanged(object sender, EventArgs e)
    {
        int i = 0;
    }

    void txt_DataBinding(object sender, EventArgs e)
    {
        TextBox txt = (TextBox)sender;
        GridViewRow gridrow = (GridViewRow)txt.NamingContainer;
        object value = DataBinder.Eval(gridrow.DataItem, ColumnName);
        if (value != null)
        {
            txt.Text = Convert.ToString(value);
        }
    }

    #endregion
}
protected void BulkEditGridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
    Response.Write("test");

}
protected void BulkEditGridView1_RowUpdated(object sender, GridViewUpdatedEventArgs e)
{
    Response.Write("GridView");
}
}



BulkEditGridView1.cs



BulkEditGridView1.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.ComponentModel;
using System.Collections;
using System.Collections.Specialized;
using System.Web;

namespace RealWorld.Grids
{
/// <summary>
/// BulkEditGridView allows users to edit multiple rows of a gridview at once, and have them
/// all saved.
/// </summary>
[
DefaultEvent("SelectedIndexChanged"),
Designer("System.Web.UI.Design.WebControls.GridViewDesigner, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"),
ControlValueProperty("SelectedValue"),
]
public class BulkEditGridView : System.Web.UI.WebControls.GridView
{
    //key for the RowInserting event handler list
    public static readonly object RowInsertingEvent = new object();

    private List<int> dirtyRows = new List<int>();
    private List<int> newRows = new List<int>();

    /// <summary>
    /// Default Constructor
    /// </summary>
    public BulkEditGridView()
    {
    }

    /// <summary>
    /// Modifies the creation of the row to set all rows as editable.
    /// </summary>
    /// <param name="rowIndex"></param>
    /// <param name="dataSourceIndex"></param>
    /// <param name="rowType"></param>
    /// <param name="rowState"></param>
    /// <returns></returns>
    protected override GridViewRow CreateRow(int rowIndex, int dataSourceIndex, DataControlRowType rowType, DataControlRowState rowState)
    {
        return base.CreateRow(rowIndex, dataSourceIndex, rowType, rowState | DataControlRowState.Edit);
    }

    public List<GridViewRow> DirtyRows
    {
        get
        {
            List<GridViewRow> drs = new List<GridViewRow>();
            foreach (int rowIndex in dirtyRows)
            {
                drs.Add(this.Rows[rowIndex]);
            }

            return drs;
        }
    }

    /// <summary>
    /// Adds event handlers to controls in all the editable cells.
    /// </summary>
    /// <param name="row"></param>
    /// <param name="fields"></param>
    protected override void InitializeRow(GridViewRow row, DataControlField[] fields)
    {
        base.InitializeRow(row, fields);
        foreach (TableCell cell in row.Cells)
        {
            if (cell.Controls.Count > 0)
            {
                AddChangedHandlers(cell.Controls);
            }
        }
    }

    /// <summary>
    /// Adds an event handler to editable controls.
    /// </summary>
    /// <param name="controls"></param>
    private void AddChangedHandlers(ControlCollection controls)
    {
        foreach (Control ctrl in controls)
        {
            if (ctrl is TextBox)
            {
                ((TextBox)ctrl).TextChanged += new EventHandler(this.HandleRowChanged);
            }
            else if (ctrl is CheckBox)
            {
                ((CheckBox)ctrl).CheckedChanged += new EventHandler(this.HandleRowChanged);
            }
            else if (ctrl is DropDownList)
            {
                ((DropDownList)ctrl).SelectedIndexChanged += new EventHandler(this.HandleRowChanged);
            }
            ////could add recursion if we are missing some controls.
            //else if (ctrl.Controls.Count > 0 && !(ctrl is INamingContainer) )
            //{
            //    AddChangedHandlers(ctrl.Controls);
            //}
        }
    }


    /// <summary>
    /// This gets called when a row is changed.  Store the id of the row and wait to update
    /// until save is called.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="args"></param>
    void HandleRowChanged(object sender, EventArgs args)
    {
        GridViewRow row = ((Control)sender).NamingContainer as GridViewRow;
        if (null != row)
        {
            if (0 != (row.RowState & DataControlRowState.Insert))
            {
                int altRowIndex = this.InnerTable.Rows.GetRowIndex(row);
                if (false == newRows.Contains(altRowIndex))
                    newRows.Add(altRowIndex);
            }
            else
            {
                if (false == dirtyRows.Contains(row.RowIndex))
                    dirtyRows.Add(row.RowIndex);
            }
        }

    }

    /// <summary>
    /// Setting this property will cause the grid to update all modified records when
    /// this button is clicked.  It currently supports Button, ImageButton, and LinkButton.
    /// If you set this property, you do not need to call save programatically.
    /// </summary>
    [IDReferenceProperty(typeof(Control))]
    public string SaveButtonID
    {
        get
        {
            return (string)(this.ViewState["SaveButtonID"] ?? String.Empty);
        }
        set
        {
            this.ViewState["SaveButtonID"] = value;
        }
    }

    /// <summary>
    /// Attaches an eventhandler to the onclick method of the save button.
    /// </summary>
    /// <param name="e"></param>
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);

        //Attach an event handler to the save button.
        if (false == string.IsNullOrEmpty(this.SaveButtonID))
        {
            Control btn = RecursiveFindControl(this.NamingContainer, this.SaveButtonID);
            if (null != btn)
            {
                if (btn is Button)
                {
                    ((Button)btn).Click += new EventHandler(SaveClicked);
                }
                else if (btn is LinkButton)
                {
                    ((LinkButton)btn).Click += new EventHandler(SaveClicked);
                }
                else if (btn is ImageButton)
                {
                    ((ImageButton)btn).Click += new ImageClickEventHandler(SaveClicked);
                }
            }
        }
    }

    /// <summary>
    /// Looks for a control recursively up the control tree.  We need this because Page.FindControl
    /// does not find the control if we are inside a masterpage content section.
    /// </summary>
    /// <param name="namingcontainer"></param>
    /// <param name="controlName"></param>
    /// <returns></returns>
    private Control RecursiveFindControl(Control namingcontainer, string controlName)
    {
        Control c = namingcontainer.FindControl(controlName);

        if (c != null)
            return c;

        if (namingcontainer.NamingContainer != null)
            return RecursiveFindControl(namingcontainer.NamingContainer, controlName);

        return null;
    }

    /// <summary>
    /// Handles the save event, and calls the save method.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void SaveClicked(object sender, EventArgs e)
    {
        this.Save();
        this.DataBind();
    }

    /// <summary>
    /// Saves any modified rows.  This is called automatically if the SaveButtonId is set.
    /// </summary>
    public void Save()
    {
        try
        {
            foreach (int row in dirtyRows)
            {
                //TODO: need to check if we really want false here.  Probably want to pull this
                //fron the save button.
                this.UpdateRow(row, false);
            }

            foreach (int row in newRows)
            {
                //Make the datasource save a new row.
                this.InsertRow(row, false);
            }
        }
        finally
        {
            dirtyRows.Clear();
            newRows.Clear();
        }
    }

    /// <summary>
    /// Prepares the <see cref="RowInserting"/> event and calls insert on the DataSource.
    /// </summary>
    /// <param name="rowIndex"></param>
    /// <param name="causesValidation"></param>
    private void InsertRow(int rowIndex, bool causesValidation)
    {
        GridViewRow row = null;

        if ((!causesValidation || (this.Page == null)) || this.Page.IsValid)
        {
            DataSourceView dsv = null;
            bool useDataSource = base.IsBoundUsingDataSourceID;
            if (useDataSource)
            {
                dsv = this.GetData();
                if (dsv == null)
                {
                    throw new HttpException("DataSource Returned Null View");
                }
            }
            GridViewInsertEventArgs args = new GridViewInsertEventArgs(rowIndex);
            if (useDataSource)
            {
                if ((row == null) &&

推荐答案

您正在动态创建所有内容,甚至包括模板列,例如使用AddTemplateFieldsToGrid();
现在,如果您看到使用上述方法在BindTableToGrid()方法中添加模板,则该方法在页面加载时首次调用,但在回发期间不会调用.
由于它是动态创建的,因此在连续的回发中,您需要重新创建它们以引发事件.如果不这样做,他们就会迷路.
发生这种情况是因为在页面加载期间首次创建的控件在回发期间不再存在.
You are creating everything dynamically, even the template columns like using AddTemplateFieldsToGrid();
Now, if you see you have used this above method to add templates in BindTableToGrid() method which is called for first time when page loads but not during postbacks.
Since, it was dynamically created, on consecutive postbacks you need to re-create them in order to raise the events. If you don''t they get lost.
This happens as the control that was created for first time during page load no more exists during post back.


这篇关于BulkEditGridView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆