1.前言
当对GridView控件进行数据绑定时,如果绑定的记录为空,网页上就不显示GridView,造成页面部分空白,页面布局结构也受影响。下面讨论的方法可以让GridView在没有数据记录的时候显示表的字段结构和显示提示信息。
GridView要绑定的字段和temple的字段一样,在这里我们利用GridView原有的功能,设定当数据为空是显示“Data Is Empty”,如果没有设定EmptyDataText属性,当绑定的记录为空时,GridView将不在页面显示。
4.数据显示
4.1普通空记录显示
编写ButtonNormalBind的事件函数ButtonNormalBind_Click,添加如下代码,来测试没有经过处理的GridView显示情况:
protected void ButtonNormalBind_Click(object sender, EventArgs e)
    {
        DataTable dt = new DataTable();
 
        dt.Columns.Add("temple_id");
        dt.Columns.Add("temple_name");
        dt.Columns.Add("location");
        dt.Columns.Add("build_date");
 
        this.GridViewEmptyDataTest.DataSource = dt;
        this.GridViewEmptyDataTest.DataBind();
}
执行这些代码后,GridView显示结果如下图所示:
 
可以看到这样简单的提示看不出GridView的结构来,在大多数的实际应用中我们希望看到GridView到底有哪些字段。
4.2增加空行来显示GridView的结构
我们知道只要GridView绑定的DataTable有一行记录,GridView就会显示表头,所以当DataTable为空时我们增加一个空行从而显示表头。
我们把代码改成如下所示:
DataTable dt = new DataTable();
 
        dt.Columns.Add("temple_id");
        dt.Columns.Add("temple_name");
        dt.Columns.Add("location");
        dt.Columns.Add("build_date");
 
        if (dt.Rows.Count == 0)
        {
            dt.Rows.Add(dt.NewRow());
        }
 
        this.GridViewEmptyDataTest.DataSource = dt;
    this.GridViewEmptyDataTest.DataBind();
在每次绑定前判断,如果为空就增加一空行,这样绑定的结果如下图所示:

可以看得表头已经可以显示了,但是显示的空行没有任何数据也让人费解,可不可以增加一下提示信息呢?
4.3增加空记录提示
我们在数据绑定后增加一些代码对GridView进行一下处理,让显示结果更友好。在this.GridViewEmptyDataTest.DataBind();后面增加代码如下所示:
int columnCount = dt.Columns.Count;
        GridViewEmptyDataTest.Rows[0].Cells.Clear();
        GridViewEmptyDataTest.Rows[0].Cells.Add(new TableCell());
        GridViewEmptyDataTest.Rows[0].Cells[0].ColumnSpan = columnCount;
        GridViewEmptyDataTest.Rows[0].Cells[0].Text = "没有记录";
     GridViewEmptyDataTest.Rows[0].Cells[0].Style.Add("text-align", "center");
改良后的显示结果如下图所示:

看来显示结果已经达到了我们的要求,但是当页面上有其他按钮操作导致页面PostBack时,页面再次显示确没有了提示信息变成如下图所示的样子:

这并不是我们想要的。
4.4防止PostBack时页面显示变化
为了防止显示改变我们在Page_Load事件里添加如下代码,从而重新绑定GridView:
if (IsPostBack)
        {
            //如果数据为空则重新构造Gridview
            if (GridViewEmptyDataTest.Rows.Count == 1 && GridViewEmptyDataTest.Rows[0].Cells[0].Text == "没有记录")
            {
                int columnCount = GridViewEmptyDataTest.Columns.Count;
                GridViewEmptyDataTest.Rows[0].Cells.Clear();
                GridViewEmptyDataTest.Rows[0].Cells.Add(new TableCell());
                GridViewEmptyDataTest.Rows[0].Cells[0].ColumnSpan = columnCount;
                GridViewEmptyDataTest.Rows[0].Cells[0].Text = "没有记录";
                GridViewEmptyDataTest.Rows[0].Cells[0].Style.Add("text-align", "center");
            }
   }
这下我们的控件终于可以按我们的要求显示了,但是为了代码的重用,当一个项目里有多个GridView时,避免充分些相同的代码,我们需要把代码封装成类,从而让所有的GridView数据绑定时都可以轻易地实现我们的要求。
4.5封装
类的封装代码如下所示:
using System.Data;
using System.Web.UI.WebControls;
 
/// <summary>
/// Gridview绑定的数据记录为空时显示Gridview的表头,并显示没有记录的提示
/// </summary>
public class GridviewControl
{
    //当Gridview数据为空时显示的信息
    private static string EmptyText = "没有记录";
 
     public GridviewControl()
     {
       
     }
 
    /// <summary>
    /// 防止PostBack后Gridview不能显示
    /// </summary>
    /// <param name="gridview"></param>
    public static void ResetGridView(GridView gridview)
    {
        //如果数据为空则重新构造Gridview
        if (gridview.Rows.Count == 1 && gridview.Rows[0].Cells[0].Text == EmptyText)
        {
            int columnCount = gridview.Columns.Count;
            gridview.Rows[0].Cells.Clear();
            gridview.Rows[0].Cells.Add(new TableCell());
            gridview.Rows[0].Cells[0].ColumnSpan = columnCount;
            gridview.Rows[0].Cells[0].Text = EmptyText;
            gridview.Rows[0].Cells[0].Style.Add("text-align", "center");
        }
    }
 
    /// <summary>
    /// 绑定数据到GridView,当表格数据为空时显示表头
    /// </summary>
    /// <param name="gridview"></param>
    /// <param name="table"></param>
    public static void GridViewDataBind(GridView gridview, DataTable table)
    {
        //记录为空重新构造Gridview
        if (table.Rows.Count == 0)
        {
            table = table.Clone();
            table.Rows.Add(table.NewRow());
            gridview.DataSource = table;
            gridview.DataBind();
            int columnCount = table.Columns.Count;
            gridview.Rows[0].Cells.Clear();
            gridview.Rows[0].Cells.Add(new TableCell());
            gridview.Rows[0].Cells[0].ColumnSpan = columnCount;
            gridview.Rows[0].Cells[0].Text = EmptyText;
            gridview.Rows[0].Cells[0].Style.Add("text-align", "center");
        }
        else
        {
            //数据不为空直接绑定
            gridview.DataSource = table;
            gridview.DataBind();
        }
 
        //重新绑定取消选择
        gridview.SelectedIndex = -1;
    }
}
你可以把这个类编译成DLL,让各个地方调用。
4.6使用示例
这个类的使用很简单,就是在每次进行数据绑定是调用GridViewDataBind,这个函数的第一个参数是要绑定数据的GridView第二个参数是包含数据字段列的DataTable,可能为空可能不空,如果数据不空,函数则自动进行正常绑定,否则显示“没有记录”的提示。
上面的按钮事件的代码可以改成如下所示:
DataTable dt = new DataTable();
        dt.Columns.Add("temple_id");
        dt.Columns.Add("temple_name");
        dt.Columns.Add("location");
        dt.Columns.Add("build_date");
GridviewControl.GridViewDataBind(this.GridViewEmptyDataTest, dt);
最后在Page_Load中对本页面所有GridView调用ResetGridView函数,如下所示:
if (IsPostBack)
        {
            GridviewControl.ResetGridView(this.GridViewEmptyDataTest);
    }

其他方法:
也是要给大家介绍的方法: 扩展GridView来实现.继承GridVie,重写Render方法,当其数据源为空时做一下处理,直接看代码吧:

    /// <summary>
    /// GridView 扩展控件
    /// @author:jianyi0115@163.com
    /// </summary>
     public class GridView : System.Web.UI.WebControls.GridView
    {       
        private bool _enableEmptyContentRender 
= true ;
        
/// <summary>
        /// 是否数据为空时显示标题行
        /// </summary>
        public bool EnableEmptyContentRender
        {
            set { _enableEmptyContentRender 
= value; }
            get { 
return _enableEmptyContentRender; }
        }

        private string _EmptyDataCellCssClass ;
        
/// <summary>
        /// 为空时信息单元格样式类
        /// </summary>
        public string EmptyDataCellCssClass
        {
            set { _EmptyDataCellCssClass 
= value ; }
            get { 
return _EmptyDataCellCssClass ; }
        }

        
/// <summary>
        /// 为空时输出内容
        /// </summary>
        /// <param name="writer"></param>
        protected virtual void RenderEmptyContent(HtmlTextWriter writer)
        {
            Table t 
= new Table(); //create a table
            t.CssClass 
= this.CssClass; //copy all property
            t.GridLines 
= this.GridLines;
            t.BorderStyle 
= this.BorderStyle;
            t.BorderWidth 
= this.BorderWidth;
            t.CellPadding 
= this.CellPadding;
            t.CellSpacing 
= this.CellSpacing;

            t.HorizontalAlign 
= this.HorizontalAlign;

            t.Width 
= this.Width;

            t.CopyBaseAttributes(
this);

            TableRow row 
= new TableRow();
            t.Rows.Add(row);

            foreach (DataControlField f 
in this.Columns) //generate table header
            {
                TableCell cell 
= new TableCell();

                cell.Text 
= f.HeaderText;

                cell.CssClass 
= "TdHeaderStyle1"; //这里把表头样式写死了

                row.Cells.Add(cell);
            }

            TableRow row2 
= new TableRow();
            t.Rows.Add(row2);

            TableCell msgCell 
= new TableCell();
            msgCell.CssClass 
= this._EmptyDataCellCssClass;

            
if (this.EmptyDataTemplate != null) //the second row, use the template
            {
                
this.EmptyDataTemplate.InstantiateIn(msgCell);
            }
            
else //the second row, use the EmptyDataText
            {
                msgCell.Text 
= this.EmptyDataText;
            }

            msgCell.HorizontalAlign 
= HorizontalAlign.Center;
            msgCell.ColumnSpan 
= this.Columns.Count;

            row2.Cells.Add(msgCell);

            t.RenderControl(writer);
       }

        protected override 
void  Render(HtmlTextWriter writer)
        {
            
if ( _enableEmptyContentRender && ( this.Rows.Count == 0 || this.Rows[0].RowType == DataControlRowType.EmptyDataRow) )
            {
                RenderEmptyContent(writer);
            }
            
else
            {
                base.Render(writer);
            }
        }    

    }
}

 

相关文章: