我推荐你用 flexgrid的。net版本

解决方案 »

  1.   

    using System;using System.Web.UI;using System.Web.UI.WebControls;using System.ComponentModel;using System.Diagnostics;using System.IO;//using System.Web.UI.Design.WebControls;using System.Text;using System.Drawing; [assembly:TagPrefix("Microsoft.Gtec.Dsv", "gtecdsv")] namespace Microsoft.Gtec.Dsv{ /// <summary> /// Summary description for WebCustomControl1. /// </summary> [ToolboxData("<{0}:hhDataGrid runat=server></{0}:hhDataGrid>")] public class  hhDataGrid: System.Web.UI.WebControls.DataGrid { protected override void Render(HtmlTextWriter output) { //Use this flag to determine whether the component is in design-time or runtime. //The control will be rendered differently in IDE. //Don't bother to use DataGridDesigner.GetDesignTimeHtml bool designMode = ((Site != null) && (Site.DesignMode)); //Backing up the properties need to change during the render process string tempLeft = Style["LEFT"]; string tempTop = Style["TOP"]; Unit tempHeight = Height; string tempTableStyle = Style["TABLE-LAYOUT"];  //Render a "<div>" container with scrollbars. output.WriteBeginTag("div"); output.WriteAttribute("id",ID + "_div"); output.WriteAttribute("style", "HEIGHT: " + Height + ";" + //Leave 20px for the vertical scroll bar, //assuming the end-user will not set his scroll bar to more than 20px. "WIDTH: " + (Width.Value + 20) + "px;" +  "TOP: " + Style["TOP"] + ";" + "LEFT: " + Style["LEFT"] + ";" + "POSITION: " + Style["POSITION"] + ";" +  "OVERFLOW-X: auto;" + "Z-INDEX: " + Style["Z-INDEX"] + ";" + //Render the scrollbar differently for design-time and runtime. "OVERFLOW-Y: " + (designMode?"scroll":"auto") ); output.Write(HtmlTextWriter.TagRightChar);                         //The DataGrid is inside the "<div>" element, so place it at (0,0). Style["LEFT"] = "0px"; Style["TOP"] = "0px"; //Render the DataGrid. base.Render(output); output.WriteEndTag("div"); //Restore the values Style["LEFT"] = tempLeft; Style["TOP"] = tempTop;  //The following rendering is only necessary under runtime. It has negative impact during design time. if (!designMode)  { //Render another copy of the DataGrid with only headers. //Render it after the DataGrid with contents, //so that it is on the top. Z-INDEX is more complex here. //Set Height to 0, so that it will adjust on its own. Height = new Unit("0px"); StringWriter sw = new StringWriter(); HtmlTextWriter htw = new HtmlTextWriter(sw); //This style is important for matching column widths later. Style["TABLE-LAYOUT"] = "fixed"; base.Render(htw); StringBuilder sbRenderedTable = sw.GetStringBuilder(); htw.Close(); sw.Close(); Debug.Assert((sbRenderedTable.Length > 0), "Rendered HTML string is empty. Check viewstate usage and databinding."); string temp = sbRenderedTable.ToString(); if (sbRenderedTable.Length > 0) { //AllowPaging at the top? if ((AllowPaging) && ((PagerPosition.Top == PagerStyle.Position || (PagerPosition.TopAndBottom == PagerStyle.Position))))  { Trace.WriteLine(temp); sbRenderedTable.Replace(ID,ID + "_Pager", 0, (temp.IndexOf(ID) + ID.Length)); temp = sbRenderedTable.ToString(); string pager = temp.Substring(0, temp.ToLower().IndexOf(@"</tr>") + 5); Trace.WriteLine(pager); output.Write(pager); output.WriteEndTag("table"); //Start of pager's <tr> int start = temp.ToLower().IndexOf(@"<tr"); //End of pager's </tr> int end = temp.ToLower().IndexOf(@"</tr>") + 5; //Remove the <tr> for pager from the string. Prepare to render the headers. sbRenderedTable.Remove(start,end-start); Trace.WriteLine(sbRenderedTable.ToString()); sbRenderedTable.Replace(ID + "_Pager",ID + "_Headers", 0, (temp.IndexOf(ID+"_Pager") + (ID+"_Pager").Length)); temp = sbRenderedTable.ToString(); string tableHeaders = temp.Substring(0, (temp.ToLower()).IndexOf(@"</tr>") + 5); Trace.WriteLine(tableHeaders); output.Write(tableHeaders); output.WriteEndTag("table"); string headerID = ID + "_Headers"; string pagerID = ID + "_Pager"; string divID = ID + "_div"; string adjustWidthScript = @"                             <script language=javascript>                                                        //debugger;                                                        var headerTableRow = " + headerID + @".rows[0];                                                        var originalTableRow = " + ID + @".rows[1];" //Adjust header row's height. + @"                                                        headerTableRow.height = originalTableRow.offsetHeight;                                                        " + //Adjust pager row's height, width. pagerID + @".rows[0].height = " + ID + @".rows[0].offsetHeight;                                                        " + pagerID + @".style.width = " + ID + @".offsetWidth;                                                        for (var i = 0; i < headerTableRow.cells.length; i++) {                                                                headerTableRow.cells[i].width = originalTableRow.cells[i].offsetWidth;                                                        }                                                        " +  //Also needs to adjust the width of the "<div>" at client side in addition to servier side, //since the Table's actual width can go beyond the width specified at server side under Edit mode.
      

  2.   

    //The server side width manipulation is mainly for design-time appearance. divID + @".style.width = " + ID + @".offsetWidth + 20 + 'px';                                                                " + //The following script is for flow-layout. We cannot get the position of the control //on server side if the the page is with flow-layout. headerID + @".style.left = " + divID + @".offsetLeft;                                                                " + headerID + @".style.top = " + divID + @".offsetTop + " + pagerID + @".offsetHeight;                                                                " +  headerID + @".style.position = 'absolute';                                                                " + pagerID + @".style.left = " + divID + @".offsetLeft;                                                                " + pagerID + @".style.top = " + divID + @".offsetTop;                                                                " + pagerID + @".style.position = 'absolute';                                                </script>"; Page.RegisterStartupScript("dummyKey" + this.ID, adjustWidthScript); //output.Write(adjustWidthScript); }  else  { //Replace the table's ID with a new ID. //It is tricky that we must only replace the 1st occurence,  //since the rest occurences can be used for postback scripts for sorting. sbRenderedTable.Replace(ID,ID + "_Headers", 0, (temp.IndexOf(ID) + ID.Length)); Trace.WriteLine(sbRenderedTable.ToString()); //We only need the headers, stripping the rest contents. temp = sbRenderedTable.ToString(); string tableHeaders = temp.Substring(0, (temp.ToLower()).IndexOf(@"</tr>") + 5); Trace.WriteLine(tableHeaders); output.Write(tableHeaders); output.WriteEndTag("table"); //Client side script for matching column widths. //Can't find a way to do this on the server side, since the browser can change widths on the client side. string adjustWidthScript = @"                                                <script language=javascript>                                                        //debugger;                                                        var headerTableRow = " + this.ID + @"_Headers.rows[0];                                                        var originalTableRow = " + this.ID + @".rows[0];                                                        headerTableRow.height = originalTableRow.offsetHeight;                                                        for (var i = 0; i < headerTableRow.cells.length; i++) {                                                                headerTableRow.cells[i].width = originalTableRow.cells[i].offsetWidth;                                                        }                                                        " +  //Also needs to adjust the width of the "<div>" at client side in addition to servier side, //since the Table's actual width can go beyond the width specified at server side under Edit mode. //The server side width manipulation is mainly for design-time appearance. this.ID + "_div" + @".style.width = " + this.ID + @".offsetWidth + 20 + 'px';                                                                " + //The following script is for flow-layout. We cannot get the position of the control //on server side if the the page is with flow-layout. this.ID + "_Headers" + @".style.left = " + this.ID + @"_div.offsetLeft;                                                                " + this.ID + "_Headers" + @".style.top = " + this.ID + @"_div.offsetTop;                                                                " +  this.ID + "_Headers" + @".style.position = 'absolute';                                                </script>"; Page.RegisterStartupScript("dummyKey" + this.ID, adjustWidthScript); //output.Write(adjustWidthScript); } Height = tempHeight; Style["TABLE-LAYOUT"] = tempTableStyle; } } }                 protected override void OnInit(EventArgs e) { if (0 == Width.Value) Width = new Unit("400px"); if (0 == Height.Value) Height = new Unit("200px"); //Transparent header is not allowed. if (HeaderStyle.BackColor.IsEmpty)  { HeaderStyle.BackColor = Color.White; } //Transparent pager is not allowed. if (PagerStyle.BackColor.IsEmpty)  { PagerStyle.BackColor = Color.White; }  base.OnInit (e); }  [Browsable(false)] public override bool ShowHeader { get { return true; } set { if (false == value) throw new InvalidOperationException("Use the original DataGrid to set ShowHeaders to false."); } } }}
      

  3.   

    (C#版)*控件*有横向和竖向的滚动条的DataGrid(横向支持从第几列滚动) 
    http://blog.csdn.net/rickjelly2004/archive/2004/12/14/216227.aspx
    创建跨多列、多行表头的DataGrid
    http://dev.csdn.net/develop/article/18/18971.shtm
      

  4.   

    设置dataGrid1.RowHeadersVisible = true;
    dataGrid1.RowHeaderWidth = 你要固定列的宽度和;,然后在dataGrid1的OnPaint事件中重绘固定列
      

  5.   

    http://www.syncfusion.com/FAQ/WinForms/FAQ_c44c.asp