sticky
ASP.NET数据表现控件常见问题 RRS feed

全部回复

  •  

    1. GridView控件

      

    1.1在不使用数据源控件时,GridView控件的排序和分页  [回到顶端]

     

    有时你想在不使用数据源控件如SqlDataSourceObjectDataSource 控件的情况下绑定GridView控件到数据,这意味着排序和分页将不会借助数据源控件被自动处理,为了实现排序和分页,你必须要处理GridView 控件的PageIndexChanging Sorting事件,如下例所示:

      

    protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
    {
        GridView1.DataSource = SortDataTable(GetYourDataSource(), true);
        GridView1.PageIndex = e.NewPageIndex;
        GridView1.DataBind();
    }
     
    private string GridViewSortDirection
    {
        get { return ViewState["SortDirection"] as string ?? "ASC"; }
        set { ViewState["SortDirection"] = value; }
    }
     
    private string GridViewSortExpression
    {
        get { return ViewState["SortExpression"] as string ?? string.Empty; }
        set { ViewState["SortExpression"] = value; }
    }
     
    private string ToggleSortDirection()
    {
        switch (GridViewSortDirection)
       {
          case "ASC":
                GridViewSortDirection = "DESC";
              break;
          case "DESC":
                GridViewSortDirection = "ASC";
              break;
       }
        return GridViewSortDirection;
    }
     
    protected DataView SortDataTable(DataTable dataTable, bool isPageIndexChanging)
    {
        if (dataTable != null)
       {
            DataView dataView = new DataView(dataTable);
            if (GridViewSortExpression != string.Empty)
           {
                if (isPageIndexChanging)
               {
                    dataView.Sort = string.Format("{0} {1}", 
                                  GridViewSortExpression,GridViewSortDirection);
               }
               else
               {
                    dataView.Sort = string.Format("{0} {1}",
                                  GridViewSortExpression,ToggleSortDirection());
               }
           }
        return dataView;
       }
       else
       {
            return new DataView();
       }
    }
     
    protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
    {
        GridViewSortExpression = e.SortExpression;
        int pageIndex = GridView1.PageIndex;
        GridView1.DataSource = SortDataTable(GetYourDataSource(), false);
        GridView1.PageIndex = pageIndex;
        GridView1.DataBind();
    }

      

    相关帖子:

    GridView控件的动态排序

    如何在GridView控件中排序与分页

     


    If you have any feedback on this FAQ please send it to fbmsdn@microsoft.com
    2009年7月20日 9:42
  •   

    1.2 如何显示空的GridView控件?  [回到顶端]

     

    GridView中没有数据要显示时,默认情况控件将不被显示。如果你想即便在没有数据时也显示标题行,你可以创建一个临时的包含空记录的DataTable对象,接着在页面的Init事件中绑定该GridView控件到这个DataTable。下例说明了如何去做。

     

    protected void GridView1_Init(Object sender, EventArgs e)

    {

        DataTable dt = new DataTable();

        dt.Columns.Add("Column1");

        dt.Columns.Add("Column2");

        DataRow dr = dt.NewRow();

        dr["Column1"] = "";

        dr["Column2"] = "";

        dt.Rows.Add(dr);

        GridView1.DataSource = dt;

        GridView1.DataBind();

      }

     

    另一种解决方法是从GridView继承并重写CreateChildControls方法,该方法能自动利用现有列布局,并移除使用外在DataTable对象的需求。下例说明了如何去做。

     

    public class EmptyGridView : GridView

    {

        #region Properties

        /// <summary>

        /// Enable or Disable generating an empty table if no data rows in source

        /// </summary>

        [

        Description("Enable or disable generating an empty table with headers

             when no data rows are available in the data source."),

        Category("Misc"),

        DefaultValue("true"),

        ]

        public bool ShowEmptyTable

        {

            get

            {

                object o = ViewState["ShowEmptyTable"];

                return (o != null ? (bool)o : true);

            }

            set

            {

                ViewState["ShowEmptyTable"] = value;

            }

        }

        /// <summary>

        /// Get or Set Text to display in empty data row

        /// </summary>

        [

        Description("Text to display in the empty data row."),

        Category("Misc"),

        DefaultValue(""),

        ]

        public string EmptyTableRowText

        {

            get

            {

                object o = ViewState["EmptyTableRowText"];

                return (o != null ? o.ToString() : "");

            }

            set

            {

                ViewState["EmptyTableRowText"] = value;

            }

        }

        #endregion

        protected override int CreateChildControls(System.Collections.IEnumerable

                dataSource, bool dataBinding)

        {

            int numRows = base.CreateChildControls(dataSource, dataBinding);

            // No data rows created, so create an empty table if enabled.

            if (numRows == 0 && ShowEmptyTable)

            {

                //create table

                Table table = new Table();

                table.ID = this.ID;

                //create a new header row

                GridViewRow row = base.CreateRow(-1, -1, DataControlRowType.Header,

                    DataControlRowState.Normal);

                //convert the exisiting columns into an array and initialize

                DataControlField[] fields = new

                    DataControlField[this.Columns.Count];

                this.Columns.CopyTo(fields, 0);

                this.InitializeRow(row, fields);

                table.Rows.Add(row);

                //create the empty row

                row = new GridViewRow(-1, -1, DataControlRowType.DataRow,

                DataControlRowState.Normal);

                TableCell cell = new TableCell();

                cell.ColumnSpan = this.Columns.Count;

                cell.Width = Unit.Percentage(100);

                cell.Controls.Add(new LiteralControl(EmptyTableRowText));

                row.Cells.Add(cell);

                table.Rows.Add(row);

                this.Controls.Add(table);

            }

            return numRows;

        }

    }

     

    相关帖子:

    当SqlDataSource控件没有返回数据时,如何显示Gridview的页眉和页脚

      


    If you have any feedback on this FAQ please send it to fbmsdn@microsoft.com
    2009年7月20日 9:42
  •   

    1.3 GridView的大小溢出  [回到顶端]

      

    如果GridView控件试图显示超过页面可提供空间的列或行时,这将引起GridView控件溢出并改变整个页面的外观,你可以通过添加水平或垂直滚动条到该控件去解决这个问题,如下例所示:

     

    <div style="vertical-align:top; height:200px; width:100%; overflow:auto;">

      

    相关帖子:

    在GridView控件中需要一个滚动条

     

      

    1.4 Gridview控件中使用CheckBox控件  [回到顶端]

     

    在基于webe-mail客户端,如Hotmail Yahoo,一个包含check boxes的列可用于选择单个e-mail信息,当前Gridview控件并没有提供对此的内置支持,但你自己可以实现它。关于如何扩展Gridview控件去实现check boxes的例子,请参见此论坛:http://msdn.microsoft.com/en-us/magazine/cc163612.aspx

     

    相关帖子

    如何在GridView控件中添加CheckBox

    如何在GridView控件中从所有页面中选择所有行

    在GridView控件中访问CheckBox控件

     

      

    1.5 绑定自定义页面模板  [回到顶端]

      

    要在页脚显示如总页数的信息,你可以用<PagerTemplate>项,如下例所示:

     

    <asp:GridView ID="GridView1" runat="server"

        DataSourceID="SqlDataSource1"

        DataKeyNames="ID"

        AllowPaging="true"

        PageSize="10"

        AutoGenerateColumns="true">

      <PagerTemplate>

        <asp:Label ID="LabelCurrentPage" runat="server"

            Text="<%# ((GridView)Container.NamingContainer).PageIndex + 1 %>">

        </asp:Label>/

        <asp:Label ID="LabelPageCount" runat="server"

           Text="<%# ((GridView)Container.NamingContainer).PageCount %>">

        </asp:Label> 

        <asp:LinkButton ID="LinkButtonFirstPage" runat="server"

            CommandArgument="First"

            CommandName="Page"

            enabled="<%# ((GridView)Container.NamingContainer).PageIndex != 0

                 %>"><<

        asp:LinkButton ID="LinkButtonPreviousPage" runat="server"

            CommandArgument="Prev" CommandName="Page"

            enabled="<%# ((GridView)Container.NamingContainer).PageIndex != 0 %>"><

        </asp:LinkButton>

        <asp:LinkButton ID="LinkButtonNextPage" runat="server"

            CommandArgument="Next"

            CommandName="Page"

            enabled="<%# ((GridView)Container.NamingContainer).PageIndex !=

                ((GridView)Container.NamingContainer).PageCount - 1 %>">>

        </asp:LinkButton>

        <asp:LinkButton ID="LinkButtonLastPage" runat="server"

            CommandArgument="Last"

            CommandName="Page"

            enabled="<%# ((GridView)Container.NamingContainer).PageIndex !=

             ((GridView)Container.NamingContainer).PageCount - 1 %>">>>

        </asp:LinkButton>

      </PagerTemplate>

    </asp:GridView>

     

     

    1.6 如何访问页码按钮,并改变其样式?  [回到顶端]

      

    要自定义选中的页码,使其有更大的字体或不同的颜色,需处理GridView控件的RowDataBound事件,并编程性地应用格式。接下来的例子演示了如何去做。

     

    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)  

    {  

        if (e.Row.RowType == DataControlRowType.Pager)  

        {  

            TableRow row = e.Row.Controls[0].Controls[0].Controls[0] as TableRow;

            foreach (TableCell cell in row.Cells)  

            {  

                Control lb = cell.Controls[0] ;  

                if (lb is Label)  

                {                              

                    ((Label)lb).ForeColor = System.Drawing.Color.Red;  

                    ((Label)lb).Font.Size = new FontUnit("40px");

                }  

                else if (lb is LinkButton)  

                {                       

                     //Here is for changing the rest LinkButton page number.

                }  

            }

        }  

    }

        

      

    1.7 如何导出gridviewExcel文件?  [回到顶端]

     

    如何导出Gridview数据到Excel文件,请遵循这些步骤:

    1.  在包含GridView的页面中,重写VerifyRenderingInServerForm方法。这让你编程地呈现GridView控件而不用呈现完整的页面。这个方法的默认执行阻止你单独的呈现GridView控件。 

    2.  确保GridView控件位于包含runat="server"属性的form元素中。

     

    下面的例子演示了为了呈现GridView 控件为Excel电子表格的必须代码。

     

    protected void Button1_Click(object sender, System.EventArgs e)

    {

        // Clear the response.

        Response.Clear();

        // Set the type and file.name.

        Response.AddHeader("content-disposition",

            "attachment;filename=FileName.xls");

        Response.Charset = "";

        Response.ContentType = "application/vnd.xls";

        // Add the HTML from the GridView control to a StringWriter instance so you

        // can write it out later.

        System.IO.StringWriter sw = new System.IO.StringWriter();

        System.Web.UI.HtmlTextWriter hw = new HtmlTextWriter(sw);

        GridView1.RenderControl(hw);

        // Write the data.

        Response.Write(sw.ToString);

        Response.End();

    }

    pupublic override void VerifyRenderingInServerForm(Control control)

    {

    }

     

    相关帖子:

    输出到Excel

     

       

    1.8 如何在e-mail信息中发送Gridview数据?  [回到顶端]

      

    你可以作为e-mail信息的一部分发送显示在Gridview中的数据。这种技术类似于你如何输出Gridview数据到Excel文件(你从Gridview控件得到展现标记,并添加到e-mail消息中)。确保e-mail消息是HTML格式。下面例子演示了如何去做(这个例子假设应用程序已经被配置为发送e-mail)。

     

    using System.IO;

    using System.Text;

    using System.Net.Mail;

    private string GridViewToHtml(GridView gv)

    {

        StringBuilder sb = new StringBuilder();

        StringWriter sw = new StringWriter(sb);

        HtmlTextWriter hw = new HtmlTextWriter(sw);

        gv.RenderControl(hw);

        return sb.ToString();

    }

    protected void SendMailButton_Click(object sender, EventArgs e)

    {

        MailMessage mail = new MailMessage();

        mail.Body = GridViewToHtml(GridView1);

        mail.IsBodyHtml = true;

        // ...   

    }

    public override void VerifyRenderingInServerForm(Control control)

    {

    }

     


    If you have any feedback on this FAQ please send it to fbmsdn@microsoft.com
    2009年7月20日 9:43
  •  

    2. DataList 控件  [回到顶端]

     

    2.1 水平地呈现数据  [回到顶端]

      

    Gridview控件一行接一行地显示数据,这意味着布局是垂直的。要以其它的布局呈现数据,Datalist控件是个好的选择。例如,他可以通过设置RepeatDirection="Horizontal"水平地显示数据。你同样可以使用Repeatcolumns属性去控制在每一行显示多少列。

     

     

    2.2 DataList控件的分页  [回到顶端]

      

    不同于Gridview控件,Datalist控件没有自动分页支持。要支持分页功能,你必须添加代码,如下例所示:

     

    int PageSize, RecordCount, PageCount, CurrentPage;

    SqlConnection MyConn;

    public int IndexOfPage

    {

        get { return (int)ViewState["_IndexOfPage"]; }

        set { ViewState["_IndexOfPage "] = value; }

    }

    public int CountOfPage

    {

        get { return (int)ViewState["_CountOfPage"]; }

        set { ViewState["_CountOfPage"] = value; }

    }

    public void Page_Load(Object src, EventArgs e)

    {

        PageSize = 3;

        string MyConnString =

         @"Server=(local)\SQLEXPRESS;Integrated Security=SSPI;Database=test;Persist Security Info=True";

        MyConn = new SqlConnection(MyConnString);

        MyConn.Open();

        if (!Page.IsPostBack)

        {

            ListBind();

            CurrentPage = 0;

            IndexOfPage = 0;

            RecordCount = CalculateRecord();

            lblRecordCount.Text = RecordCount.ToString();

            PageCount = RecordCount / PageSize;

            lblPageCount.Text = PageCount.ToString();

            CountOfPage = PageCount;

        }

    } 

    public int CalculateRecord()

    {

        int intCount;

        string strCount = "select count(*) as co from student";

        SqlCommand MyComm = new SqlCommand(strCount, MyConn);

        SqlDataReader dr = MyComm.ExecuteReader();

        if (dr.Read())

        {

            intCount = Int32.Parse(dr["co"].ToString());

        }

        else

        {

            intCount = 0;

        }

        dr.Close();

        return intCount;

    }

    ICollection CreateSource()

    {

        int StartIndex;

        StartIndex = CurrentPage * PageSize;

        string strSel = "select * from student";

        DataSet ds = new DataSet();

        SqlDataAdapter MyAdapter = new SqlDataAdapter(strSel, MyConn);

        MyAdapter.Fill(ds, StartIndex, PageSize, "Score");

        return ds.Tables["Score"].DefaultView;

    }

    public void ListBind()

    {

        DataList1.DataSource = CreateSource();

        DataList1.DataBind();

        lbnNextPage.Enabled = true;

        lbnPrevPage.Enabled = true;

        if (CurrentPage == (PageCount - 1)) lbnNextPage.Enabled = false;

        if (CurrentPage == 0) lbnPrevPage.Enabled = false;

        lblCurrentPage.Text = (CurrentPage + 1).ToString();

    }

    public void Page_OnClick(Object sender, CommandEventArgs e)

    {

        CurrentPage = (int)IndexOfPage;

        PageCount = (int)CountOfPage;

        string cmd = e.CommandName;

        switch (cmd)

        {

            case "next":

                if (CurrentPage < (PageCount - 1)) CurrentPage++;

                break;

            case "prev":

                if (CurrentPage > 0) CurrentPage--;

                break;

        }

        IndexPage = CurrentPage;

        ListBind();

    }

     

    相关帖子:

    DataList分页

     

      

    3. DetailsView 控件  [回到顶端]

     

    3.1/详细情况  [回到顶端]

      

    如果你想在Griview控件中显示所有记录,并且希望能够显示一条记录的细则。你需要使用另一个显示控件。一种方发是在Gridview控件中添加一个Select按钮列去显示选择的数据记录,你通常为此使用Detailsview控件。更多信息,参见ASP.NET 网站上的Master-Details

     

     

    4. 常见问题  [回到顶端]

     

    4.1 如何在数据呈现控件中动态创建列?  [回到顶端]

      

    当你不确定你应该添加多少列到Gridview控件时,你可以使用自定义模板控件动态创建列,如下例所示:

     

    protected void Page_Load(object sender, EventArgs e)

    {

            if (!IsPostBack)

            {

                TemplateField customField1 = new TemplateField();

                customField1.ShowHeader = true;

                customField1.HeaderTemplate =

                    new GridViewTemplate(DataControlRowType.Header, "ID", "");

                customField1.ItemTemplate =

                    new GridViewTemplate(DataControlRowType.DataRow, "", "Contract");

                GridView1.Columns.Add(customField1);

                GridView1.DataSource = GetDataSource();

                GridView1.DataBind();

            }

    }

     

    public class GridViewTemplate : ITemplate

    {

        private DataControlRowType templateType;

        private string columnName;

        private string columnNameBinding;

        public GridViewTemplate(DataControlRowType type, string colname,

            string colNameBinding)

        {

            templateType = type;

            columnName = colname;

            columnNameBinding = colNameBinding;

        }

        public void InstantiateIn( System.Web.UI.Control container )

        {

            switch (templateType)

            {

                case DataControlRowType.Header:

                    Literal lc = new Literal();

                    lc.Text = columnName;         

                    container.Controls.Add(lc);         

                    break;

                case DataControlRowType.DataRow:

                    CheckBox cb = new CheckBox();

                    cb.ID = "cb1";

                    cb.DataBinding += new EventHandler(this.cb_OnDataBinding); 

                    container.Controls.Add(cb);

                    break;

                default:

                    break;

            }

        }

        public void cb_OnDataBinding(object sender, EventArgs e)

       {

            CheckBox cb = (CheckBox)sender;

            GridViewRow container = (GridViewRow)cb.NamingContainer;

            cb.Checked = Convert.ToBoolean(

                ((DataRowView)container.DataItem)[columnNameBinding].ToString());

        }

    }

     

    相关帖子:

    自定义GridView字段的文章

    如何创建一个动态GridView控件

     

      

    4.2 连接字符串的设置  [回到顶端]

      

    你可以在Web.config文件中或在代码中配置连接字符串,更多信息参见ASP.NET网站Connection Strings Configuration

     

    相关帖子:

    Web.config文件中的连接字符串

    连接字符串问题

     

     

    4.3 如何在GridViewDataGrid中显示固定宽度的列?  [回到顶端]

      

    默认情况下,Gridview和Datagrid控件依据它们的内容自动调整列大小。要为列指定固定宽度,设置每个Tablecell对象的Width属性并设置Wrap属性为False。下面的例子显示了如何通过使用DataGrid控件去做。

     

    protected void DataGrid1_ItemCreated(object sender, DataGridItemEventArgs e)

    {

        ListItemType lit = e.Item.ItemType;

        if (lit == ListItemType.Header)

        {

            for (int i = 0; i < e.Item.Cells.Count; i++)

            {

                e.Item.Cells[i].Width = Unit.Pixel(50);

                e.Item.Cells[i].Wrap = false;

            }

        }

    }

     

      

    4.4 何时使用GridView/DataGrid/DataList/Repeater控件?  [回到顶端]

      

    关于应该使用哪一个数据呈现控件的信息,参见MSDN网站上的Deciding when to use the DataGrid, DataList, or Repeater

     

    2009年7月20日 9:45
  • 慢慢注入脑袋里面,向各位MVP前辈学习

    2009年10月28日 8:50
  • 人的脑袋要是能刻录就好了!
    2009年11月19日 8:20
  • 学习了 不错 哈哈
    2009年11月24日 7:41
  • 谢谢各位大哥,再次感谢

    2010年1月29日 9:14
  • 猛谢各位大侠了
    2010年5月10日 14:32
  • protected void Button1_Click(object sender, EventArgs e)
        {
            SqlParameter[] values = new SqlParameter[]
            {
             new SqlParameter("@tablename","Admin"),
             new SqlParameter("@varname","AdminName="+TextBox1.Text),
            };
            string strcon = ConfigurationManager.ConnectionStrings["con"].ConnectionString;
            SqlConnection con = new SqlConnection(strcon);
            con.Open();
            SqlCommand cmd = new SqlCommand("Select_Login", con);
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Parameters.AddRange(values);
            SqlDataReader dr = cmd.ExecuteReader();
            if (dr.Read())
            {
                Response.Write("henggong");
            }
            else
            {
                Response.Write("shibai");
            }
        }


    ALTER PROCEDURE  Select_Login
      (   
      @tablename   varchar(20),   
      @varname   varchar(20),
      @name varchar(10)
       
      )   
      AS     
      declare   @varsql   varchar(200)   
      set   @varsql   ='select  * from '+@tablename+' where '+@varname
      exec(@varsql)   

    这个为什么就不能实现。  我想实现对一个存储过程的重载  通过传递不同的表名 和字段 实现不同的功能。各位大哥给小弟看看
    这个问题如何解决  老提示 “=” 附近有错误
    2010年5月18日 12:09
  • 学习加收藏

    2010年5月26日 7:50
  • 人的脑袋要是能刻录就好了!bags

    good!学习了
    i want bags
    2010年12月8日 3:57
  • 基本不用GridView.....
    2010年12月9日 7:12
  • 讲的很好,学习了!
    2011年1月27日 1:30
  • 不错的例子。
    2011年4月9日 18:56
  • data binding biz

    data view templete

    2011年4月9日 19:15
  • 非常好啊,仔细学习
    2011年7月4日 5:03
  • protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
    {
      GridViewSortExpression = e.SortExpression;
      int pageIndex = GridView1.PageIndex;
      GridView1.DataSource = SortDataTable(GetYourDataSource(), false);
      GridView1.PageIndex = pageIndex;
       GridView1.DataBind();
    }

     

    中第四行会不会是 int pageIndex = e.PageIndex;

    2011年7月4日 5:08
  • Good ~
    2011年11月24日 3:38
  • very good,I need it!

    活性炭椰壳活性炭:http://www.hyhxtc.com

    2012年4月19日 13:01
  • 哇哦 好东东
    2013年1月24日 1:36