|
|
GridView既强大又好用。为了让它更强大、更好用,我们来写一个继承自GridView的控件。
[索引页]
[源码下载]
扩展GridView控件(5) - 固定指定行、指定列
作者: webabcd
/*正式版的实现 开始*/
介绍
扩展GridView控件:
固定指定行、指定列,根据RowType固定行,根据RowState固定行
使用方法(设置FixRowColumn复合属性):
FixRowType - 需要固定的行的RowType(用逗号“,”分隔)
FixRowState - 需要固定的行的RowState(用逗号“,”分隔)
FixRows - 需要固定的行的索引(用逗号“,”分隔)
FixColumns - 需要固定的列的索引(用逗号“,”分隔)
TableWidth - 表格的宽度
TableHeight - 表格的高度
关键代码
css
 /**//*固定行*/
.yy_sgv_fixRow
 { }{
position: relative; top: expression(this.offsetParent.scrollTop - 1);
}
 /**//*固定列*/
.yy_sgv_fixCol
 { }{
position: relative; left: expression(this.offsetParent.scrollLeft - 1);
}
 /**//*高优先级的固定*/
.yy_sgv_fixHigh
 { }{
z-index: 9999;
}
 /**//*低优先级的固定*/
.yy_sgv_fixLow
 { }{
z-index: 1000;
}
c#
using System;
using System.Collections.Generic;
using System.Text;

using System.Web.UI.WebControls;
using System.Web.UI;

namespace YYControls.SmartGridViewFunction
  {
 /**//// <summary>
/// 扩展功能:固定指定行、指定列
/// </summary>
public class FixRowColumnFunction : ExtendFunction
 {
 /**//// <summary>
/// 构造函数
/// </summary>
public FixRowColumnFunction()
: base()
 {

}

 /**//// <summary>
/// 构造函数
/// </summary>
/// <param name="sgv">SmartGridView对象</param>
public FixRowColumnFunction(SmartGridView sgv)
: base(sgv)
 {

}

 /**//// <summary>
/// 扩展功能的实现
/// </summary>
protected override void Execute()
 {
this._sgv.RowDataBoundCell += new SmartGridView.RowDataBoundCellHandler(_sgv_RowDataBoundCell);
this._sgv.RenderBegin += new SmartGridView.RenderBeginHandler(_sgv_RenderBegin);
this._sgv.RenderEnd += new SmartGridView.RenderEndHandler(_sgv_RenderEnd);
}

 /**//// <summary>
/// SmartGridView的RowDataBoundCell事件
/// </summary>
/// <param name="sender"></param>
/// <param name="gvtc"></param>
void _sgv_RowDataBoundCell(object sender, GridViewTableCell gvtc)
 {
TableCell tc = gvtc.TableCell;
GridViewRow gvr = (GridViewRow)tc.Parent;

int i = 0; // 0-既不固定行也不固定列;1-固定行或固定列;2-既固定行也固定列
// 固定行
if
(
(
!String.IsNullOrEmpty(this._sgv.FixRowColumn.FixRows)
&&
 Array.Exists(this._sgv.FixRowColumn.FixRows.Split(','), delegate(string s) { return s == gvr.RowIndex.ToString(); })
)
||
(
!String.IsNullOrEmpty(this._sgv.FixRowColumn.FixRowType)
&&
 Array.Exists(this._sgv.FixRowColumn.FixRowType.Split(','), delegate(string s) { return s == gvr.RowType.ToString(); })
)
||
(
!String.IsNullOrEmpty(this._sgv.FixRowColumn.FixRowState)
&&
 Array.Exists(this._sgv.FixRowColumn.FixRowState.Split(','), delegate(string s) { return s == gvr.RowState.ToString(); })
)
)
 {
i++;
Helper.Common.SetAttribute(tc, "class", "yy_sgv_fixRow", AttributeValuePosition.Last, ' ');
}
// 固定列
if
(
!String.IsNullOrEmpty(this._sgv.FixRowColumn.FixColumns)
&&
 Array.Exists(this._sgv.FixRowColumn.FixColumns.Split(','), delegate(string s) { return s == gvtc.ColumnIndex.ToString(); })
)
 {
i++;
Helper.Common.SetAttribute(tc, "class", "yy_sgv_fixCol", AttributeValuePosition.Last, ' ');
}

// 低等级的z-index
if (i == 1)
 {
Helper.Common.SetAttribute(tc, "class", "yy_sgv_fixLow", AttributeValuePosition.Last, ' ');
}
// 高等级的z-index
else if (i == 2)
 {
Helper.Common.SetAttribute(tc, "class", "yy_sgv_fixHigh", AttributeValuePosition.Last, ' ');
}
}

 /**//// <summary>
/// RenderBegin
/// </summary>
/// <param name="sender"></param>
/// <param name="writer"></param>
void _sgv_RenderBegin(object sender, HtmlTextWriter writer)
 {
writer.AddStyleAttribute(HtmlTextWriterStyle.Overflow, "auto");
writer.AddStyleAttribute(HtmlTextWriterStyle.Position, "relative");
writer.AddStyleAttribute(HtmlTextWriterStyle.Width, String.IsNullOrEmpty(this._sgv.FixRowColumn.TableWidth) ? "100%" : this._sgv.FixRowColumn.TableWidth);
writer.AddStyleAttribute(HtmlTextWriterStyle.Height, String.IsNullOrEmpty(this._sgv.FixRowColumn.TableHeight) ? "100%" : this._sgv.FixRowColumn.TableHeight);
writer.RenderBeginTag(HtmlTextWriterTag.Div);
}

 /**//// <summary>
/// RenderEnd
/// </summary>
/// <param name="sender"></param>
/// <param name="writer"></param>
void _sgv_RenderEnd(object sender, HtmlTextWriter writer)
 {
writer.RenderEndTag();
}
}
}
/*正式版的实现 结束*/
/*测试版的实现 开始*/
介绍
平时使用GridView的时候会有固定表头、指定行或指定列的需求,就像Excel冻结行、列那样。其实我们可以用CSS来搞定。扩展一下GridView,通过设置几个属性来达到这样的功能。
控件开发
1、新建一个继承自GridView的类,另外为了保持滚动条状态,还要继承IPostBackDataHandler接口
 /**//// <summary>
/// 继承自GridView
/// </summary>
[ToolboxData(@"<{0}:SmartGridView runat='server'></{0}:SmartGridView>")]
public class SmartGridView : GridView, IPostBackDataHandler
 {

}

2、新建一个FixRowCol类,有七个属性
using System;
using System.Collections.Generic;
using System.Text;

using System.ComponentModel;

namespace YYControls.SmartGridView
  {
 /**//// <summary>
/// 固定表头、指定行或指定列的实体类
/// </summary>
[TypeConverter(typeof(ExpandableObjectConverter))]
public class FixRowCol
 {
private bool _isFixHeader;
 /**//// <summary>
/// 固定表头否?
/// </summary>
[Description("固定表头否?"), Category("扩展"), DefaultValue(false), NotifyParentProperty(true)]
public virtual bool IsFixHeader
 {
 get { return _isFixHeader; }
 set { _isFixHeader = value; }
}

private bool _isFixPager;
 /**//// <summary>
/// 固定分页行否?
/// </summary>
[Description("固定分页行否?"), Category("扩展"), DefaultValue(false), NotifyParentProperty(true)]
public virtual bool IsFixPager
 {
 get { return _isFixPager; }
 set { _isFixPager = value; }
}

private string _fixRowIndices;
 /**//// <summary>
/// 需要固定的行的索引(用逗号“,”分隔)
/// </summary>
[Description("需要固定的行的索引(用逗号“,”分隔)"), Category("扩展"), NotifyParentProperty(true)]
public virtual string FixRowIndices
 {
 get { return _fixRowIndices; }
 set { _fixRowIndices = value; }
}

private string _fixColumnIndices;
 /**//// <summary>
/// 需要固定的列的索引(用逗号“,”分隔)
/// </summary>
[Description("需要固定的列的索引(用逗号“,”分隔)"), Category("扩展"), NotifyParentProperty(true)]
public virtual string FixColumnIndices
 {
 get { return _fixColumnIndices; }
 set { _fixColumnIndices = value; }
}

private System.Web.UI.WebControls.Unit _tableWidth;
 /**//// <summary>
/// 表格的宽度
/// </summary>
[Description("表格的宽度"), Category("扩展"), NotifyParentProperty(true)]
public System.Web.UI.WebControls.Unit TableWidth
 {
 get { return _tableWidth; }
 set { _tableWidth = value; }
}

private System.Web.UI.WebControls.Unit _tableHeight;
 /**//// <summary>
/// 表格的高度
/// </summary>
[Description("表格的高度"), Category("扩展"), NotifyParentProperty(true)]
public System.Web.UI.WebControls.Unit TableHeight
 {
 get { return _tableHeight; }
 set { _tableHeight = value; }
}

private bool _enableScrollState;
 /**//// <summary>
/// 是否保持滚动条的状态
/// </summary>
[Description("是否保持滚动条的状态"), Category("扩展"), DefaultValue(false), NotifyParentProperty(true)]
public bool EnableScrollState
 {
 get { return _enableScrollState; }
 set { _enableScrollState = value; }
}

 /**//// <summary>
/// ToString();
/// </summary>
/// <returns></returns>
public override string ToString()
 {
return "FixRowCol";
}
}
}

3、在继承自GridView的类中加一个复杂对象属性,该复杂对象就是第2步创建的那个FixRowCol
private FixRowCol _fixRowCol;
 /**//// <summary>
/// 固定表头、指定行或指定列
/// </summary>
[
Description("固定表头、指定行或指定列"),
Category("扩展"),
DefaultValue(""),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerProperty)
]
public virtual FixRowCol FixRowCol
 {
get
 {
if (_fixRowCol == null)
 {
_fixRowCol = new FixRowCol();
}
return _fixRowCol;
}
}
4、重写OnRowDataBound以设置每个单元格的样式,从而实现固定表头、指定行或指定列的功能。
 /**//// <summary>
/// OnRowDataBound
/// </summary>
/// <param name="e"></param>
protected override void OnRowDataBound(GridViewRowEventArgs e)
 {
if (e.Row.RowType == DataControlRowType.Pager)
 {
if (FixRowCol.IsFixPager)
 {
if (this.PagerSettings.Position == PagerPosition.Top || (this.PagerSettings.Position == PagerPosition.TopAndBottom && _isTopPager))
 {
// TopPager固定行和列
e.Row.Cells[0].Attributes.Add("style", "z-index:999; position: relative; top: expression(this.offsetParent.scrollTop); left: expression(this.offsetParent.scrollLeft);");
// 现在是TopPager,之后就是BottomPager了,所以设置_isTopPager为false
_isTopPager = false;
}
else if (this.PagerSettings.Position == PagerPosition.TopAndBottom && !_isTopPager)
 {
// BottomPager只固定列
e.Row.Cells[0].Attributes.Add("style", "z-index:999; position: relative; left: expression(this.offsetParent.scrollLeft);");
// 现在是BottomPager,之后就是TopPager了,所以设置_isTopPager为true
_isTopPager = true;
}
}
}

if (e.Row.RowType == DataControlRowType.DataRow || e.Row.RowType == DataControlRowType.Header)
 {
// 给每一个指定固定的列的单元格加上css属性
if (!String.IsNullOrEmpty(FixRowCol.FixColumnIndices))
 {
// 列索引
foreach (string s in FixRowCol.FixColumnIndices.Split(','))
 {
int i;
if (!Int32.TryParse(s, out i))
throw new ArgumentException("FixColumnIndices", "含有非整形的字符");
if (i > e.Row.Cells.Count)
throw new ArgumentOutOfRangeException("FixColumnIndices", "溢出");

e.Row.Cells[i].Attributes.Add("style", "position: relative; left: expression(this.offsetParent.scrollLeft);");
}
}

bool isFixRow = false; // 当前行是否固定
if (FixRowCol.IsFixHeader && e.Row.RowType == DataControlRowType.Header)
 {
isFixRow = true;
}

if (!String.IsNullOrEmpty(FixRowCol.FixRowIndices) && e.Row.RowType == DataControlRowType.DataRow)
 {
// 行索引
foreach (string s in FixRowCol.FixRowIndices.Split(','))
 {
int i;
if (!Int32.TryParse(s, out i))
throw new ArgumentException("FixRowIndices", "含有非整形的字符");
if (i > e.Row.Cells.Count)
throw new ArgumentOutOfRangeException("FixRowIndices", "溢出");

if (i == e.Row.RowIndex)
 {
isFixRow = true;
break;
}
}
}

// 固定该行
if (isFixRow)
 {
// 该行的每一个单元格
for (int j = 0; j < e.Row.Cells.Count; j++)
 {
// 该单元格不属于固定列
if (String.IsNullOrEmpty(e.Row.Cells[j].Attributes["style"]) || e.Row.Cells[j].Attributes["style"].IndexOf("position: relative;") == -1)
 {
e.Row.Cells[j].Attributes.Add("style", " position: relative; top: expression(this.offsetParent.scrollTop);");
}
// 该单元格属于固定列
else
 {
e.Row.Cells[j].Attributes.Add("style", e.Row.Cells[j].Attributes["style"] + "top: expression(this.offsetParent.scrollTop); z-index: 666;");
}
}
}
}

base.OnRowDataBound(e);
}

5、增加两个私有变量
 /**//// <summary>
/// 如果固定行、列的话 滚动条的x位置
/// </summary>
private int _yy_SmartGridView_x;
 /**//// <summary>
/// 如果固定行、列的话 滚动条的y位置
/// </summary>
private int _yy_SmartGridView_y;

6、重写GridView的OnPreRender方法,用于注册两个HiddenField,以及注册设置GridView的滚动条的位置的javascript代码
 /**//// <summary>
/// OnPreRender
/// </summary>
/// <param name="e"></param>
protected override void OnPreRender(EventArgs e)
 {
if (FixRowCol.EnableScrollState)
 {
// 滚动条x位置
Page.ClientScript.RegisterHiddenField("yy_SmartGridView_x", _yy_SmartGridView_x.ToString());
// 滚动条y位置
Page.ClientScript.RegisterHiddenField("yy_SmartGridView_y", _yy_SmartGridView_y.ToString());

// 设置GridView的滚动条的位置
Page.ClientScript.RegisterStartupScript(
this.GetType(),
"jsSetScroll", "<script type=\"text/javascript\">document.getElementById('yy_ScrollDiv').scrollLeft=" + _yy_SmartGridView_x + ";document.getElementById('yy_ScrollDiv').scrollTop=" + _yy_SmartGridView_y + ";</script>"
);

// 将控件注册为要求在页回发至服务器时进行回发处理的控件
if (Page != null) Page.RegisterRequiresPostBack(this);
}

base.OnPreRender(e);
}

7、重写GridView的Render方法,将GridView用一个div包裹起来。
 /**//// <summary>
/// Render
/// </summary>
/// <param name="writer"></param>
protected override void Render(HtmlTextWriter writer)
 {
// 给GridView一个容器 <div>
if (!FixRowCol.TableWidth.IsEmpty || !FixRowCol.TableHeight.IsEmpty)
 {
if (FixRowCol.TableWidth.IsEmpty) FixRowCol.TableWidth = new Unit(100, UnitType.Percentage);
if (FixRowCol.TableHeight.IsEmpty) FixRowCol.TableHeight = new Unit(100, UnitType.Percentage);

writer.Write("<div id='yy_ScrollDiv' style=\"overflow: auto; width: "
+ FixRowCol.TableWidth.ToString() + "; height: "
+ FixRowCol.TableHeight.ToString() + "; position: relative;\" ");

// 如果保持滚动条的状态的话,用隐藏字段记录滚动条的位置
if (FixRowCol.EnableScrollState)
 {
writer.Write("onscroll=\"document.getElementById('yy_SmartGridView_x').value = this.scrollLeft; document.getElementById('yy_SmartGridView_y').value = this.scrollTop;\">");
}
else
 {
writer.Write(">");
}
}

base.Render(writer);

// </div> 结束
if (!FixRowCol.TableWidth.IsEmpty || !FixRowCol.TableHeight.IsEmpty)
 {
writer.Write("</div>");
}
}

8、获取存储了滚条位置信息的HiddenField的值
void IPostBackDataHandler.RaisePostDataChangedEvent()
 {

}

bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection postCollection)
 {
// 获取两个保存了 固定行、列后 的GridView滚动条的位置信息
_yy_SmartGridView_x = String.IsNullOrEmpty(postCollection["yy_SmartGridView_x"]) ? 0 : Convert.ToInt32(postCollection["yy_SmartGridView_x"]);
_yy_SmartGridView_y = String.IsNullOrEmpty(postCollection["yy_SmartGridView_y"]) ? 0 : Convert.ToInt32(postCollection["yy_SmartGridView_y"]);

return false;
}

控件使用
添加这个控件到工具箱里,然后拖拽到webform上,设置其FixRowCol下的7个属性即可。IsFixHeader是固定表头否?;IsFixPager是固定分页行否?;FixRowIndices是需要固定的行的索引(用逗号“,”分隔);FixColumnIndices是需要固定的列的索引(用逗号“,”分隔);TableWidth是表格的宽度;TableHeight是表格的高度;EnableScrollState为是否保持滚动条的状态
ObjData.cs
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using System.ComponentModel;

 /**//// <summary>
/// OjbData 的摘要说明
/// </summary>
public class OjbData
  {
public OjbData()
 {
//
// TODO: 在此处添加构造函数逻辑
//
}

[DataObjectMethod(DataObjectMethodType.Select, true)]
public DataTable Select()
 {
DataTable dt = new DataTable();
dt.Columns.Add("no", typeof(string));
dt.Columns.Add("name", typeof(string));

for (int i = 0; i < 30; i++)
 {
DataRow dr = dt.NewRow();
dr[0] = "no" + i.ToString().PadLeft(2, '0');
dr[1] = "name" + i.ToString().PadLeft(2, '0');

dt.Rows.Add(dr);
}

return dt;
}
}

Default.aspx
 <% @ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>SmartGridView测试</title>
</head>
<body>
<form id="form1" runat="server">
<yyc:SmartGridView ID="SmartGridView1" runat="server" AutoGenerateColumns="False"
DataSourceID="ObjectDataSource1" Width="1000px">
<Columns>
<asp:BoundField DataField="no" HeaderText="序号" SortExpression="no" />
<asp:BoundField DataField="name" HeaderText="名称" SortExpression="name" />
<asp:BoundField DataField="no" HeaderText="序号" SortExpression="no" />
<asp:BoundField DataField="name" HeaderText="名称" SortExpression="name" />
<asp:BoundField DataField="no" HeaderText="序号" SortExpression="no" />
<asp:BoundField DataField="name" HeaderText="名称" SortExpression="name" />
<asp:BoundField DataField="no" HeaderText="序号" SortExpression="no" />
<asp:BoundField DataField="name" HeaderText="名称" SortExpression="name" />
<asp:BoundField DataField="no" HeaderText="序号" SortExpression="no" />
<asp:BoundField DataField="name" HeaderText="名称" SortExpression="name" />
</Columns>
<FixRowCol FixColumnIndices="0,1" FixRowIndices="0" IsFixHeader="True" TableHeight="300px"
TableWidth="300px" EnableScrollState="true" />
</yyc:SmartGridView>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="Select"
TypeName="OjbData"></asp:ObjectDataSource>
</form>
</body>
</html>

/*测试版的实现 结束*/
OK
[源码下载]
Feedback
能否用.net3.0进行扩展一下,也就是WPF。
谢谢!我现在项目中这样的控件。
按你的思路,如何用WPF来翻译。
在线等待,谢谢!
@plentiful
我扩展的这个是web的啊,和wpf没什么关系啊
我的GRID WIDTH设的是100%,然后我现在想把他就是说当宽度超了以后有横向的滚动条,能不能给我点见意啊?
#119楼 [楼主] 回复 引用 查看
2008-04-02 15:26 by webabcd
@理想天空
可以的
我提供的SmartGridView的demo里的第二个例子就是这样的
可是我看到的第二个例子你的smartgridview 设宽度是1050px,啊,
@理想天空
不会啊
我又看了一遍
是Width="100%"啊
难到是我看错了?SmartGridView.aspx这里你设的是Width="1200"
SmartGridViewAlpha.aspx这里你设的是Width="1050"
@理想天空
晕,咱们说岔了
那个例子是
SmartGridView.aspx页的
的ID为sgv2的控件
<yyc:SmartGridView ID="sgv2" runat="server" AllowPaging="True" AllowSorting="true"
PageSize="20" DataSourceID="ObjectDataSource1" MouseOverCssClass="OverRow" DataKeyNames="name"
Width="1200" BoundRowDoubleClickCommandName="DoubleClick" OnRowCommand="sgv_RowCommand"
ContextMenuCssClass="RightMenu">
这个你设的也是1200啊,我刚才用js 实现了,我通过对比他没撑开的宽度和撑开的宽度,如果撑开了就把他外面那个DIV设成固定的,谢谢了
@理想天空
:)
不好意思,我理解错了,我以为说的是GridView外面的div
还好,问题解决了就好
HI webabcd
貌似固定表头的做法在Firefox下面无效啊
@LanceZhang
是的,因为ff不支持css+expression
谢谢搂主的控件,非常好用。
但和 理想天空 有同样的问题。因对JS不是很熟,能否提供118楼的所说的JS源码。
谢谢!
@ciger
:)
全部源码都有的
按文中提供的地址下载就好了
楼主您好,非常感谢您共享这么好的控件。 有几处疑问能否帮忙解答以下: 1. 这个控件我能够用在我们公司内部网站上面吗?有没有版权上的问题? 2. 我试用了一下,发现在firefox上,好像不起作用,但是在IE上锁定列非常好用。 3. 我引入yyControls.dll后,并没有发现SmartGridViewAlpha 控件,只有SmartGridView 4. 在试用SmartGridView时,发现没有IsFixHeader这个属性,是不是SmartGridView不支持锁定header? 另外如果我不设置任何css的话,拖动卷屏条,隐藏的内容会重叠在锁定行,或者锁定列的后面。是我有什么设置不对吗? 非常感谢楼主:)
@FlyFox2008
:)
1、随便用,随便改
2、是的,扩展的这些功能,只有这项不支持ff,因为ff不支持css+expression
3、SmartGridViewAlpha是测试版的,所以默认是不选的,你可以找到再勾选,源代码里也都有
4、正式版的这个功能的使用方法
FixRowType - 需要固定的行的RowType(用逗号“,”分隔)
FixRowState - 需要固定的行的RowState(用逗号“,”分隔)
FixRows - 需要固定的行的索引(用逗号“,”分隔)
FixColumns - 需要固定的列的索引(用逗号“,”分隔)
TableWidth - 表格的宽度
TableHeight - 表格的高度
需要设样式,不然都是透明的,就会造成你所说的情况
@FlyFox2008
:)
不谢
一般早中晚各一次上blog
楼主您好。我是一个C#的初学者,因为开发一个项目。想用楼主的扩展控件,我把控件引入到项目中,没有做任何动作。只是添加了这个控件。当运行这个页面的时候出现“控件包含代码块(即 <% ... %>),因此无法修改控件集合”,但是我单独另外起一个空项目写一个页面。却可以用。是不是和我这个项目的某些什么东西有关呢?C#不熟,请赐教,谢谢
我试着把母版页中<head runat="server">的runat="server"去掉。上面错误就不会出现了。但是却出现了另外一个错误。“未将对象引用设置到对象的实例”。不知道是为何
原来是因为我在head里面涉及到一些<%=Request.ApplicationPath%>这种代码。所以才出现以上错误。
楼主,我这里也出现了124楼的问题。就是拖动卷屏条,隐藏的内容会重叠在锁定行,或者锁定列的后面。您说是和css有关系。关于css的相关设计是不是在你的demo里都可以找到的呢?谢谢
@Dragon61
去了<head runat="server">,就不能用主题了
demo里有css的示例,你可以参考一下
楼主您好。上面的问题都已经解决了。现在碰到一个新问题。就是我发现当动态绑定数据源的时候。分页功能就不行了。提示“激发了未处理的事件“PageIndexChanging”。 ”,那是不是意味着我要重新写过分页功能呢?
我在您的源码例子里面做了如下的改动。把数据源绑定改成了动态的。
protected void Page_Load(object sender, EventArgs e)
{
OjbData getdt = new OjbData();
sgv1.DataSource = getdt.Get();
///绑定控件的数据
sgv1.DataBind();
}
也出现了“激发了未处理的事件“PageIndexChanging”的错误。不知道该如何解决?
真激動,看到樓主的回復.
我今天測試使用了一下您的控件.遇到一些問題.可能是我設置上的問題,希望能得到您的幫助.
1. 您在您的控件(SmartGridView)里有個PagerSettings,其中有個 Position屬性,可以設置在Top,Bottom或者TopAndBottom,我有測試一下.Top就一定沒有問題,但是設置為Bottom和TopAndBottom的時候都有問題.如果設置為Bottom,下面有一對空白,但是看不到翻頁的選項,設置為 TopAndBottom時,Top可以看到,Bottom依然無法看到.
2. 我設置為Top后,翻頁時,報出PageIndexChanging事件沒有的錯誤.後自行建立該事件,錯誤就沒了.一切正常.看了您的Source Code.并沒有看到您設置這個事件,但是也一切正常,實在費解.
3. 此時并沒有使用 PagingMode="Webabcd". (問題好像描述顛倒了).因為我一開始很想使用您控件自帶的那種翻頁功能,可能是設置有問題,所以即使 Position的位置 設置在Top,上面的那些東西都擠在一堆了..我說的那些東西是
"首页","上一页","下一页","末页"等等..翻頁需要用到的那些.并沒有平鋪到整個Header.
幾次比對屬性設置,沒能找到差異.奇怪.
望能得到您的答復.萬分感謝.
不好意思.我的表達真的有問題.
這里補充一下..
上面的第3點.我的意思是.
在1,2的情況下.都沒有設置 PagingMode="Webabcd".
而第3點時,是想完全按照您提供的Sample來做翻頁.所以有設置PagingMode="Webabcd"了.然后東西都擠在左上角,寬度和我要固定的前兩個Column的寬度一樣了.并沒有等于整個GridView的Header寬度.
如果還有沒能表達明白的問題,還請您見諒,然后說出來,我會再重新表達.抱歉.
再次感謝.
@小2
:)
1、PagerSettings是GridView的原有属性,设置为Bottom看不到,是因为把它固定了,所以如果有滚动条,那么就会把它覆盖,又由于它被固定了,所以看不到
2、3、比较麻烦了,因为我没遇到过那些问题
方便的话可以msn交流一下
我的msn
webabcd
hotmail
com
非常感谢楼主提供的这个控件,我正头痛这个固定行和列的功能。
我也遇到了124楼的透明问题。但由于对css很不在行,不知道要怎么设置属性可以不透明。楼主可不可以教下怎么设置可以解决那个透明的问题啊?
(我也看了你的源代码,但还是没有看明白~~ :$)
多谢!
@bdwang
简单的说
设置header的背景色就好了
我用自定义的数据源绑定的时候也是出现下面这个问题了。
GridView“SmartGridView1”激发了未处理的事件“PageIndexChanging”。
上面的的都没有说怎么解决。能否告诉一下。
你可以加我QQ251201521说谢谢了。
着急
@fenggang
:)
不用数据源控件的话,要自己写分页事件
一般不上qq
msn吧
webabcd
hotmail
com
///
<yyc:SmartGridView ID="SmartGridView1" runat="server" DataSourceID="SqlDataSource1" AutoGenerateColumns="False" AllowPaging="True" PageSize="20" Width="800px" MouseOverCssClass="tdbgmouseover2" OnRowCommand="SmartGridView1_RowCommand" OnRowDeleting="SmartGridView1_RowDeleting" DataKeyNames="id" >
<Columns>
<asp:HyperLinkField DataNavigateUrlFields="id" DataNavigateUrlFormatString="~/member/TeacherInfo.aspx?id={0}"
DataTextField="id" HeaderText="编号" />
<asp:HyperLinkField DataTextField="OneTeacherName" HeaderText="名称" DataNavigateUrlFields="id" DataNavigateUrlFormatString="~/member/TeacherInfo.aspx?id={0}" />
<asp:BoundField DataField="TeacherSex" HeaderText="性别" SortExpression="TeacherSex" />
<asp:BoundField DataField="Mobile" HeaderText="联系电话" SortExpression="Mobile" />
<asp:BoundField DataField="MQSF" HeaderText="身份" SortExpression="MQSF" />
<asp:BoundField DataField="SchoolGrade" HeaderText="授课年级" SortExpression="SchoolGrade" />
<asp:BoundField DataField="SpecialSkill" HeaderText="授课科目" SortExpression="SpecialSkill" />
<asp:BoundField DataField="BMTime" HeaderText="报名时间" SortExpression="BMTime" />
<asp:BoundField DataField="SHZT" HeaderText="审核通过" SortExpression="SHZT"/>
<asp:ButtonField HeaderText="审核" CommandName="shenhe" SortExpression="SHZT" FooterText="审核" Text="审核" />
<asp:TemplateField ShowHeader="False">
<itemtemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="False"
CommandName="Delete" Text="删除" OnClientClick="return confirm('你确定要删除吗?')"></asp:LinkButton>
</itemtemplate>
</asp:TemplateField>
</Columns>
<CustomPagerSettings PagingMode="Webabcd" TextFormat="每页{0}条/共{1}条 第{2}页/共{3}页 " />
<PagerSettings FirstPageText="首页" LastPageText="末页" NextPageText="下一页" PreviousPageText="上一页" />
<RowStyle Height="25px" />
</yyc:SmartGridView>
我的view页面是这样取值。但是我怎么在RowCommand方法里面没有得到“id”和“OneTeacherName”的值啊。
我是用string id = this.SmartGridView1.Rows[Convert.ToInt32(e.CommandArgument)].Cells[0].Text;取值的。
从第三个可以取值了。我是用string id = this.SmartGridView1.Rows[Convert.ToInt32(e.CommandArgument)].Cells[2].Text; 这样就可以。
能问下是为什么吗?着急。
@fenggang
BoundField可以通过.Text得到值
HyperLinkField之类的控件是要FindControl的
能不能给写个在RowCommand事件里面怎么用FindControl取HyperLinkField的值的例子啊。已经晕了好级天了。谢谢。
@fenggang
:)
我当初也是对RowCommand不爽啊
因为GridViewCommandEventArgs不能取到触发事件的RowIndex
GridViewCommandEventArgs常用下面三个属性
CommandArgument,CommandName,CommandSource
你可以页面上设置CommandArgument为行的index,然后RowCommand里取到它,然后根据它结合GridView去FindControl
请问,为何我的滚动条不出来,现在表内容太多,横向的都被截了;非得把 <yyc:SmartGridView Width="1200" Height="300" >中Height值设成<FixRowColumn FixRowType="Header,Pager" TableHeight="400px" TableWidth="800px" FixColumns="0,1" />中的Height值小滚动条才会出来
@kergee
外层div控件可以自动加的
利用div的scroll来实现冻结行、列
按你的设置在我提供的demo试了一下,没问题啊
@bancx
这玩意已经不再更新了
兄弟有兴趣的话可以在这基础上改吧改吧,或者自己重写一个,对理解GridView和自定义控件还是很有帮助的
楼主,我直接将object数据源变为sqldatasource为何就不能固定列了?谢谢
@bancx
没试过,不过感觉应该和数据源控件的类型无关
另外,强烈建议不要使用sqldatasource
难到楼主的控件不能用于sqldatasource?
楼主,我想请教一下,我设计的全是挺长的报表,用什么方法好呢,sliver light tools中提供了锁定列的功能了吗?谢谢楼主
楼主大大,非常感谢你的控件,简直太牛了。 有一问题请教(不好意思,我是新手),我采用动态绑定数据,代码大致如下: smartGridView.DataSource = myDatatable; smartGridView.DataBind();
然后我想指定每一列的宽度和不让header换行, 我试图用如下方式去做(前2列是静态的列,写在aspx文件里)在RowDataBind事件写如下代码 if (e.Row.RowType == DataControlRowType.DataRow) { DataTable dt = searchGrid.DataSource as DataTable; int colCount = dt.Columns.Count; if (e.Row.RowIndex == dt.Rows.Count - 1) { for (int i = 2; i < colCount; i++) { searchGrid.Columns[i].ItemStyle.Width = (dt.Columns[i].ToString().Length * 30); searchGrid.Columns[i].HeaderStyle.Wrap = false; searchGrid.Columns[i].HeaderStyle.Width = (dt.Columns[i].ToString().Length * 30); } }
}
结果程序报错:out of the index,我跟踪发现searchGrid.Columns.count = 2, 也就是说只有静态加载的2列,请问大大,我哪里搞错了,应该如何去设定每列的宽度和不让换行
再次对楼主大大表示感谢,提供这么好的控件还对我们这些网友不厌其烦的指导.:)
@bancx
:)
不建议用sqldatasource,因为它破坏了清晰的分层结构
能用sl当然好,有锁定列,拖动列,动态改变列宽等很多的功能
@wonder2000
:)
怎么动态生成列的?
顶死了宽度后不让换行的话可以通过css的设置overflow:hidden;white-space:nowrap;
就是读取表后采用绑定grid的方式,因为这个grid要显示不同的表,所以不能在aspx里面把绑定列写死。 smartGridView.DataSource = myDatatable; smartGridView.DataBind();
另外overflow:hidden;white-space:nowrap; 这句话写在那里?直接写在yyc:SmartGridView 的cssClass上,或者HeaderStyle的 CssClass 多谢大大,回复好快,呵呵。
@wonder2000
动态绑定列也有好几种方式,看你如何绑定了,总之要绑定上之后再遍历
比如td里加个div,在div上写
hh,搞定了,多谢大大。 我弄错了,不能在e.Row.Columns.Length上遍历,要在e.Row.Cells.Count上遍历。
@wonder2000
:)
不用谢我
是你自己搞定的
问一下,这个控件能不能做到像别的第三方控件一样外面宽度给他赋100%然后如果宽了自己出滚动条,长度也是跟据本页面的长度出滚动条?
如果可以能不能告诉我一下怎么做的?我用JS控件经常有问题
@理想天空
没试过
TableWidth - 容器的宽度
TableHeight - 容器的高度
Width - GridView本身的宽度
你可以自己试试调调,原理就是css+expression,如果不行的话只能靠你自己改源代码了,我不打算再更新这个了
非常感谢!
搞定了,我发出来如果有也跟我一样可以参考
.GridDiv
{
width:expression(document.documentElement.clientWidth -30);
height:expression(document.documentElement.clientHeight-this.offsetTop -30);
overflow:auto;
}
把这个样式赋给GRID外的DIV
高度-top是因为这样可以跟据GRID位置去判断需要的高度
不过滚动条的宽度还是搞不定如果不-30就IE会出滚动条,有兴趣的朋友可以帮我看看,谢谢
@理想天空
cool
很简短的语句就实现了,不过其他浏览器不支持,ie8也不支持
类型“YYControls.FixRowCol”不具有名为“EnableScrollState”的公共属性。
楼主你好,下载了源码后加入了你的那些代码后不能运行,报的上面那个错,如果可以,能发个正式版的代码给我吗?或者我只要单独的dataview固定列和行的控件。固定的问题让我头痛了很久,万分感谢!
@Osiris
“下载了源码后加入了你的那些代码后不能运行”
是什么意思?
文中给的下载地址,就是最后的版本,每个功能块的源代码都是分开的
最后的版本里去掉了EnableScrollState属性,如果需要用到这个属性的话可以参看测试版中的实现逻辑
楼主不好意思看错了,你给的源码例子是可以看到效果的,我现在不用datasource数据源,自己写的连数据库代码为什么固定不了表头啊?连滚动条都没出来-_-!! 还有如果是用自己写的连接数据库代码,排序功能无法实现?
分页我知道只能自己写分页事件。
还有就是你这里的代码是什么意思呢?
protected void sgv_RowCommand(object sender, GridViewCommandEventArgs e)
{
string s = "";
s += "ControlID:" + ((YYControls.SmartGridView)sender).ID + "<br />";
s += "CommandName:" + e.CommandName + "<br />";
s += "CommandArgument:" + e.CommandArgument.ToString() + "<br />";
result.InnerHtml = s + "<br />";
}
不好意思我NET比较菜,麻烦楼主了
前台
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="test.aspx.cs" Inherits="test" %>
<%@ Register Assembly="YYControls" Namespace="YYControls" TagPrefix="yyc" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>SmartGridView测试</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<yyc:SmartGridView width="50%" id="sgvTest" runat="server" MouseOverCssClass="OverRow" AllowSorting="True" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField ItemStyle-Width="50px">
<headertemplate>
序号
</headertemplate>
<itemtemplate>
<%# Container.DataItemIndex + 1 %>
</itemtemplate>
</asp:TemplateField>
<asp:TemplateField ItemStyle-Width="50px">
<headertemplate>
<asp:CheckBox ID="all" runat="server" />
</headertemplate>
<itemtemplate>
<asp:CheckBox ID="item" runat="server" />
</itemtemplate>
</asp:TemplateField>
<asp:BoundField DataField="nid" HeaderText="nid" SortExpression="nid" />
<asp:BoundField DataField="kslbid" HeaderText="kslbid" SortExpression="kslbid" />
<asp:BoundField DataField="datetime" HeaderText="datetime" SortExpression="datetime" />
<asp:BoundField DataField="operator" HeaderText="operator" SortExpression="operator" />
<asp:BoundField DataField="optime" HeaderText="optime" SortExpression="optime" />
</Columns>
<ClientButtons>
<yyc:ClientButton BoundCommandName="Sort" AttributeValue="return confirm('确认对字段“{1}”排序吗?')" Position="First" AttributeKey="onclick"></yyc:ClientButton>
</ClientButtons>
<SmartSorting AllowMultiSorting="True" AllowSortTip="True" />
<checkedrowcssclass checkboxid="item" cssclass="SelectedRow"></checkedrowcssclass>
<CascadeCheckboxes>
<yyc:CascadeCheckbox ChildCheckboxID="item" ParentCheckboxID="all" />
</CascadeCheckboxes>
<FixRowColumn FixRowType="Header,Pager" FixRows="0" FixColumns="0,1" />
<CustomPagerSettings PagingMode="Webabcd" TextFormat="每页{0}条/共{1}条 第{2}页/共{3}页 " />
<PagerSettings Position="Top" PageButtonCount="13" FirstPageText="首页" PreviousPageText="上一页"
NextPageText="下一页" LastPageText="末页" />
</yyc:SmartGridView>
</div>
</form>
</body>
</html>
后台:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using YYControls;
public partial class test : System.Web.UI.Page
{
private DBMethod dbm = null;
protected void Page_Load(object sender, EventArgs e)
{
dbm = new DBMethod();
SmartGridView sgvTest = (SmartGridView)this.FindControl("sgvTest");
sgvTest.DataSource = dbm.GetDataTable("select * from pb_bm").DefaultView;
sgvTest.DataBind();
}
}
@Osiris
:)
如果有问题,请带着源代码调试程序,然后才好确认是哪里的问题
另外,一些基础问题,请先看看msdn
好了,原来要dataview的宽度超过100%滚动条才会出来。。
楼主你好!
如果把超出页面的行或列设为固定好像有问题,不能起到固定行列的效果。
本控件是不是只能把页面内的行或列作为固定行列
@zrq
没太明白,什么是超出页面的行
是指表格的高,超过了浏览器的高吗?那也是可以的
其实实现这个的核心就是两个css
.yy_sgv_fixRow
{
position: relative; top: expression(this.offsetParent.scrollTop - 1);
}
.yy_sgv_fixCol
{
position: relative; left: expression(this.offsetParent.scrollLeft - 1);
}
楼主,我在vb.net里使用了SmartGridView
绑定datasoure后,显示倒是显示出来了,拖动时表头也不动
但是拖动时第一行的数据和表头重合了,好难看
我只设置了fixrows的属性为-1是不是还要设置其他属性?
@菜鸟向往肉鸡
用css给表header和表body设置一下背景色
在IE7中出现如下情况,横向拖动会出现空白区域。
经测试,不用你的自定义控件,把CSS调出来到RowCreated里面给TableCell赋属性,不会出现此问题。请问在你的源码里面应该如何改善?谢谢! 
@Bob.Xie
嗯,主要修改Resources/StyleLibrary.css和FixRowColumn/FixRowColumnFunction.cs
另外,不建议用这种方法做固定行、列了,IE8都不支持了
@Bob.Xie
没更新的打算了
即使以后更新,也只会重新写了
公司最近提出一变态需求:
要求页面全自动化,用户可以任意编辑、拖动、拉大和拉小页面上的任何控件,并且改变后的页面状态要保存下来。
同时要求GridView可以实现多级嵌套、自定义表头、自定义列宽、自定义单元格里面的控件类型、可编辑、可增加行(列)、删除行(列)、排序、分页、固定表头、固定行(列)(固定列自动移动到前面)...
可支持多浏览器
如有类似此功能的控件,公司愿意发钱购买。
@Bob.Xie
:)
是有够变态
至少我没见过能完全满足你需求的控件
如果需求必须是这样的话,最好说服他们用flash或sl
|