原来的帖子:
http://www.codeproject.com/KB/custom-controls/extgridview.aspx?fid=235832&fr=26#xx0xx
这个写的一个控件。叫做ExtGridView。可以成功使用。但是我添加一个edit/select 的按钮,一点击就会出问题。
可能是在控件ExtGridView.cs程序里面e.Row.RowState == DataControlRowState.Edit需要修改一下。
出现的问题:
行 34:                 //GridView1.SelectedIndexChanged += new EventHandler(GridView1_SelectedIndexChanged);
行 35:                 GridView DetailGridView = e.Row.FindControl("GridView2") as GridView;
行 36:                 DataSet1.elelockapplyRow dataRow = (e.Row.DataItem as DataRowView).Row as DataSet1.elelockapplyRow;
行 37:                 DataSet1.elelockapplydetailDataTable dt = LockDetailAdapter.GetData(dataRow.ApplyID);
行 38:                 DetailGridView.DataSource = dt;
36行出问题。

解决方案 »

  1.   

    有一个人问同样的问题,英文:
    I would like to use this control with editing capabilities.
    When i include a command field with an edit button, i have the following error:NullReferenceException: ... System.Web.UI.WebControls.BoundField.ExtractValuesFromCell(IOrderedDictionary dictionary, DataControlFieldCell cell, DataControlRowState rowState, Boolean includeReadOnly) +133If i comment the _expCell.Add call (to add the expanding cell) in the init, it's OK.
    So i suppose there's something missing in the expCell.I've tried to put the Base.OnInit after the _expCell.Add, same thing.Does anyone have a solution ? Thanks in advance.
    他过了几天回答了,但是我没有看懂:

    I reply to myself.The solution i've found :
    - override the GridView ExtractRowValues method to remove the expCell:protected override void ExtractRowValues(System.Collections.Specialized.IOrderedDictionary fieldValues, GridViewRow row, bool includeReadOnlyFields, bool includePrimaryKey)
    {
    TableCell expCell=row.Cells[0];
    row.Cells.Remove(expCell);
    base.ExtractRowValues(fieldValues, row, includeReadOnlyFields, includePrimaryKey);
    }- In row rendering, add the expCell again if it's in edit mode :
    ...
    if (RowType == DataControlRowType.DataRow)
    {
    if (this.RowState == DataControlRowState.Edit && _expCell != null)
    Cells.AddAt(0, _expCell);
    ... 
      

  2.   

    下面是ExtGridView.cs自定义控件源代码,主要可能是this.RowState == DataControlRowState.Edit && _expCell != null问题using System;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.HtmlControls;
    using System.ComponentModel;
    namespace CustomControls
    {
    /// <summary>
    /// ExtGridViewRow extendes the standard GridView row to render the contents from the last cell as an expandible cell
    /// </summary>
    public class ExtGridViewRow : GridViewRow
    {
    private TableCell _expCell;
    private HtmlInputHidden _ihExp;
    private HtmlAnchor _ctlExpand;
    private Boolean _showExpand; /// <summary>
    /// Gets or sets a value which specifies if the expand boutton should be displayed or not for the current row.
    /// </summary>
    public Boolean ShowExpand
    {
    get { return _showExpand; }
    set { _showExpand = value; }
    }

    /// <summary>
    /// Constructor for ExtGridViewRow
    /// </summary>
    /// <param name="rowIndex"></param>
    /// <param name="dataItemIndex"></param>
    /// <param name="rowType"></param>
    /// <param name="rowState"></param>
    public ExtGridViewRow(int rowIndex, int dataItemIndex, DataControlRowType rowType, DataControlRowState rowState)
    : base(rowIndex, dataItemIndex, rowType, rowState)
    {
    }
    /// <summary>
    /// Overrides GridViewRow.OnInit to perform custom initialization of the row.
    /// </summary>
    /// <param name="e">event args</param>
    protected override void OnInit(EventArgs e)
    {
    base.OnInit(e); if (RowType == DataControlRowType.Header)
    {
    _expCell = new TableHeaderCell();
    }
    else if (RowType == DataControlRowType.DataRow)
    {
    _expCell = new TableCell(); _ctlExpand = new HtmlAnchor();
    _ctlExpand.HRef = "#";
    _ctlExpand.Attributes["onclick"] = "TglRow(this);"; _ihExp = new HtmlInputHidden();
    _ihExp.ID = "e" + this.DataItemIndex.ToString(); _expCell.Controls.Add(_ctlExpand);
    _expCell.Controls.Add(_ihExp);
    }
    if (_expCell != null)
    {
    _expCell.Width = Unit.Pixel(20); Cells.AddAt(0, _expCell);
    }
    }
    /// <summary>
    /// Overrides GridViewRow.Render to perform custom rendering of the row.
    /// </summary>
    /// <param name="writer">the HtmlTextWrite object in which the row is rendered</param>
    protected override void Render(HtmlTextWriter writer)
    {
    if (DesignMode)
    {
    base.Render(writer);
    return;
    }

    TableCell c = Cells[Cells.Count - 1];

    if (RowType == DataControlRowType.DataRow)
    {
    if (_showExpand)
    {
    ExtGridView grid = this.Parent.Parent as ExtGridView; if (_ihExp.Value == String.Empty)
    {
    _ctlExpand.InnerHtml = grid.ExpandButtonText;
    _ctlExpand.Attributes["class"] = grid.ExpandButtonCssClass;
    }
    else
    {
    _ctlExpand.InnerHtml = grid.CollapseButtonText;
    _ctlExpand.Attributes["class"] = grid.CollapseButtonCssClass;
    } c.Visible = false;
    base.Render(writer); c.Visible = true;
    c.ColumnSpan = GetVisibleCellsCount() - 1;
    c.BackColor = BackColor; if (_ihExp.Value == String.Empty)
    {
    writer.Write("<tr style='display:none'>");
    }
    else
    {
    writer.Write("<tr>");
    } c.RenderControl(writer); writer.Write("</tr>");
    if (RowIndex == grid.Rows.Count - 1)
    {
    if (
    (grid.BottomPagerRow == null && grid.FooterRow == null) ||
    (
    (grid.BottomPagerRow != null && grid.BottomPagerRow.Visible == false) && 
    grid.FooterRow != null && grid.FooterRow.Visible == false
    )
    )
    {
    writer.Write("<tr><td colspan=");
    writer.Write(c.ColumnSpan);
    writer.Write("></td></tr>");
    }
    }
    }
    else
    {
    _ctlExpand.Visible = _ihExp.Visible = false;
    c.Visible = false;
    base.Render(writer);
    } }
    else if (RowType == DataControlRowType.Header)
    {
    c.Visible = false;
    base.Render(writer);
    }
    else
    {
    base.Render(writer);
    }
    } /// <summary>
    /// Helper method which obtains the visible cells count in the current row.
    /// </summary>
    /// <returns></returns>
    private Int32 GetVisibleCellsCount()
    {
    Int32 ret = 0; foreach (TableCell c in Cells)
    {
    if (c.Visible) ret++;
    } return ret;
    }
    }
    /// <summary>
    /// ExtGridView implements the expandible GridView behaviour.
    /// </summary>
    public class ExtGridView : GridView
    {
    private String _expandButtonCssClass;
    private String _collapseButtonCssClass;
    private String _expandButtonText = "+";
    private String _collapseButtonText = "-"; /// <summary>
    /// Sets or gets the CSS class which is applied on the expand button control.
    /// </summary>
    [Category("Styles")]
    public String ExpandButtonCssClass
    {
    get { return _expandButtonCssClass; }
    set { _expandButtonCssClass = value; }
    }
    /// <summary>
    /// Sets or gets the CSS class which is applied on the collapse button control.
    /// </summary>
    [Category("Styles")]
    public String CollapseButtonCssClass
    {
    get { return _collapseButtonCssClass; }
    set { _collapseButtonCssClass = value; }
    } /// <summary>
    /// Sets or gets the expand button's text.
    /// </summary>
    [Category("Appearance")]
    public String ExpandButtonText
    {
    get { return _expandButtonText; }
    set { _expandButtonText = value; }
    } /// <summary>
    /// Sets or gets the collapse button's text.
    /// </summary>
    [Category("Appearance")]
    public String CollapseButtonText
    {
    get { return _collapseButtonText; }
    set { _collapseButtonText = value; }
    }
    /// <summary>
    /// Overrides GridView.OnInit to perform custom initialization of the control.
    /// </summary>
    /// <param name="e"></param>
    protected override void OnInit(EventArgs e)
    {
    base.OnInit(e);

    #region register script
    String script =
    @"function TglRow(ctl)
    {
    var row = ctl.parentNode.parentNode;
    var tbl = row.parentNode;
    var crow = tbl.rows[row.rowIndex + 1];
    var ihExp = ctl.parentNode.getElementsByTagName('input').item(0); tbl = tbl.parentNode; var expandClass = tbl.attributes.getNamedItem('expandClass').value;
    var collapseClass = tbl.attributes.getNamedItem('collapseClass').value;
    var expandText = tbl.attributes.getNamedItem('expandText').value;
    var collapseText = tbl.attributes.getNamedItem('collapseText').value;
    if (crow.style.display == 'none')
    {
    crow.style.display = '';
    ctl.innerHTML = collapseText;
    ctl.className = collapseClass;
    ihExp.value = '1';
    }
    else
    {
    crow.style.display = 'none';
    ctl.innerHTML = expandText;
    ctl.className = expandClass;
    ihExp.value = '';
    }
    }";

    Page.ClientScript.RegisterClientScriptBlock(GetType(), "ExtGrid", script, true);
    #endregion } /// <summary>
    /// Overrides GridView.CreateRow to create the custom rows in the grid (ExtGridViewRow).
    /// </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 new ExtGridViewRow(rowIndex, dataSourceIndex, rowType, rowState);
    }
    protected override void Render(HtmlTextWriter writer)
    {
    this.Attributes["expandClass"] = _expandButtonCssClass;
    this.Attributes["collapseClass"] = _collapseButtonCssClass;
    this.Attributes["expandText"] = _expandButtonText;
    this.Attributes["collapseText"] = _collapseButtonText; base.Render(writer);
    } }
    }