后台指定GridView的ItemTemplate

     其实工作之后做的第一个项目就不提倡使用服务器控件了,不过最近在维护公司的一个老系统,其中用到了GridView。

     新需求是在GridView表头上添加排序功能。原有效果是不带分页的GridView,超出高度会显示滚动条,于是我就粗略判断此处数据量不大。采用的实现方法是直接取当前GridView的HTML作为XML数据源(IE下innerHtml获得的HTML字符串中属性值的双引号是没有的,所以此字符串不会识别成标准的XML,只有使用网上的自动补上双引号的方法才可作为XML使用),然后使用熟悉的XSLT进行排序。结果发布后没多久客服告诉我们用户反映排序很慢,问了测试人员才知道实际中有2000多条数据的情况……

     这个系统的Sping.NET+NHibernate架构我还是刚开始接触,加之系统中的业务相当复杂,在改新功能的时候一直都比较谨慎,一直保持着尽量少改动原有方法的原则。在知道了新的问题之后,我采取的实现方法是,使用AJAX发送排序请求,后台排序之后再绑定GridView然后获得GridView的HTML返回到前台,前台使用JS更新列表。

     其实页面中已经添加了GridView并且也绑定了数据,但是在实际测试的时候发现即使排序完成,IE状态栏的进度条却一直没有走完。当时判断是使用JS操作服务器控件GridView出现的问题,所以将前台的GridView删除了,而是在后台声明GridView并初始化、绑定。但是测试之后发现进度条没走完的情况依然存在,使用Fiddler监控发现每次排序完成都会请求一次csshover.htc文件,试着将查找引用csshover.htc文件的样式,发现正好是GridView的样式。于是移除此样式之后,进度条没走完的问题终于没有了。

     后台指定GridView的ItemTemplate用到的模板类如下:

public class GridViewTextTemplate : ITemplate
{
    private string templateTypeName;
    private string columnName;
    private string Id;

    public GridViewTextTemplate(string typeStr, string colname, string controlId)
    {
        templateTypeName = typeStr;
        columnName = colname;
        Id = controlId;
    }

    public void InstantiateIn(System.Web.UI.Control container)
    {
        switch (templateTypeName)
        {
            case "CheckBox":
                CheckBox checkBox = new CheckBox();
                checkBox.ID = Id;
                container.Controls.Add(checkBox);
                break;
            case "Label":
                Label label = new Label();
                label.ID = Id;
                label.DataBinding += new EventHandler(this.OnDataBinding);
                container.Controls.Add(label);
                break;
            case "HiddenField&LableInPanel":
                HiddenField hiddenField = new HiddenField();
                hiddenField.ID = "RecordID";
                hiddenField.DataBinding += new EventHandler(this.OnDataBinding);
                container.Controls.Add(hiddenField);

                Panel panel = new Panel();
                panel.CssClass = "panleStyle";
                Label labelInPanel = new Label();
                labelInPanel.ID = Id;
                labelInPanel.DataBinding += new EventHandler(this.OnDataBinding);
                panel.Controls.Add(labelInPanel);
                container.Controls.Add(panel);
                break;
            default:
                break;
        }
    }

    private void OnDataBinding(Object sender, EventArgs e)
    {
        GridViewRow row;
        if (columnName != "")
        {
            switch (templateTypeName)
            {
                case "Label":
                    Label labelInPanel = (Label)sender;
                    row = (GridViewRow)labelInPanel.NamingContainer;
                    labelInPanel.Text = Convert.ToDateTime(DataBinder.Eval(row.DataItem, columnName)).ToString("yyyy-MM-dd");
                    break;
                case "HiddenField&LableInPanel":
                    if (sender is HiddenField)
                    {
                        HiddenField hiddenField = (HiddenField)sender;
                        row = (GridViewRow)hiddenField.NamingContainer;
                        hiddenField.Value = DataBinder.Eval(row.DataItem, "ID").ToString();
                        break;
                    }
                    else if (sender is Label)
                    {
                        Label label = (Label)sender;
                        row = (GridViewRow)label.NamingContainer;
                        label.Text = DataBinder.Eval(row.DataItem, "RecordNo").ToString().Length > 18 ? DataBinder.Eval(row.DataItem, "RecordNo").ToString().Substring(0, 18) + "..." : DataBinder.Eval(row.DataItem, "RecordNo").ToString();
                    }
                    break;
                default:
                    break;
            }
        }
    }

}

使用:

    private GridView GetRecordGridView()
    {
        GridView grid_Record = new GridView();
        grid_Record.ID = "grid_Record";
        grid_Record.Width = 260;
        grid_Record.AutoGenerateColumns = false;
        grid_Record.DataKeyNames = new string[] { "Id" };
        grid_Record.CssClass = "listGridView";

        TemplateField col_chose = new TemplateField();
        col_chose.HeaderText = "选择";
        col_chose.ItemTemplate = new GridViewTextTemplate("CheckBox", "", "chkRecord");
        grid_Record.Columns.Add(col_chose);

        TemplateField col_recordID = new TemplateField();
        col_recordID.HeaderText = "单号";
        //col_recordID.ItemTemplate = new GridViewTextTemplate("HiddenField", "ID", "RecordID");
        col_recordID.ItemTemplate = new GridViewTextTemplate("HiddenField&LableInPanel", "RecordNo", "lblRecordNo");
        grid_Record.Columns.Add(col_recordID);

        TemplateField col_saveDate = new TemplateField();
        col_saveDate.HeaderText = "日期";
        col_saveDate.ItemTemplate = new GridViewTextTemplate("Label", "SaveDate", "lblSaveDate");
        grid_Record.Columns.Add(col_saveDate);

        return grid_Record;
    }

获取GridView的HTML的方法:

    public string RenderGridView(GridView grid)
    {
        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        System.IO.StringWriter sw = new System.IO.StringWriter(sb);
        HtmlTextWriter htw = new HtmlTextWriter(sw);
        grid.RenderControl(htw);

        return sb.ToString();
    }
原文地址:https://www.cnblogs.com/xuezhizhang/p/2751507.html