WinForm中的DataGridView特效问题
诸位,情况大概是这样的:我想让一个DataGridView下面固定一行,不是在下面加一行,是固定一行,即该DataGridView右边的滚动条不管如何拖动,该行都可以直接...
诸位,情况大概是这样的:我想让一个DataGridView下面固定一行,不是在下面加一行,是固定一行,即该DataGridView右边的滚动条不管如何拖动,该行都可以直接看到..固定最上面行倒是方便,不过下面固定行...就....嘿嘿,路过的大侠们看看..
展开
4个回答
展开全部
干脆直接在 DataGridView下面嵌套一个 没有列头的DataGridView 算了 frozen属性对这种要求不好使. 真要实现 需要费一番工夫 ,下面的是网络上的一个关于着方面的探索 你看看是不是有参考价值::
基本情况描述:
在DataGridView最下端加一行合计行,而且这一行是冻结不动行。
探索过程:
1)有人建议用datatable的Rows.Add+Compute来合计,但是无法实现一直在底部可见,而且输入数据的时候也很难处理,是最傻的方法。
2)有人建议用在datagridview CellPainting /RowPostPainting事件往datagridview 底部画线,画值,可是有个严重的问题是,当拖动滚动条的时候会被遮盖住了,也是一种没把最根本问题解决的思路。
3)定义一个自定义控件DataGridViewFooter,能根据DataGridView的列和值自动画表格和统计值,在 DataGridView OnPaint方法里把Footer 画出来,这是一种把根本问题解决的思路,可是难度很大。
4)做用户控件(UserControl),用两个DataGridView来显示,配合VScrollBar来显示滚动,现在本人暂时用这个方法先处理,可是在加载Column的时候很不方便,要自己写代码,浪费时间。
现在重点考虑方法3,通过Reflector窥看修改datagridview难点:
控件首先会触发OnLayout事件,把datagridview里的VScrollBar、HScrollBar、RowsHeader、ColumnHeader、Data这几个区域的位置和大小都算好,主要计算方法是PerformLayoutPrivate里的ComputeLayout,储存这些数据的是DataGridView私有变量layout。
好,明白这里后,本人在OnLayout事件之后,利用.net的反射机制,把加上DataGridViewFooter后的布局数值设置到layout去具体代码如下:
if (base.IsHandleCreated)
{
Type t = this.GetType();
FieldInfo fieldInfoLayout = t.BaseType.GetField("layout", BindingFlags.NonPublic | BindingFlags.Instance);
if (fieldInfoLayout == null) return;
Object layoutData = fieldInfoLayout.GetValue(this);
if (layoutData == null) return;
//reset layout's data and rowheader field rectangle
Type typeLayoutData = layoutData.GetType();
FieldInfo fieldInfoData = typeLayoutData.GetField("Data");
FieldInfo fieldInfoRowHeaders = typeLayoutData.GetField("RowHeaders");
MethodInfo methodInfoComputeVisibleRows = t.BaseType.GetMethod("ComputeVisibleRows", BindingFlags.NonPublic | BindingFlags.Instance);
this._dataclient = (Rectangle)fieldInfoData.GetValue(layoutData);
this._dataclient = new Rectangle(this._dataclient.X, this._dataclient.Y, this._dataclient.Width, this._dataclient.Height-this._datagridviewfooter.Height);
Rectangle rectRowHeader = (Rectangle)fieldInfoRowHeaders.GetValue(layoutData);
rectRowHeader = new Rectangle(rectRowHeader.X, rectRowHeader.Y, rectRowHeader.Width, rectRowHeader.Height - this._datagridviewfooter.Height);
fieldInfoData.SetValue(layoutData, this._dataclient);
fieldInfoRowHeaders.SetValue(layoutData, rectRowHeader);
methodInfoComputeVisibleRows.Invoke(this, null);
fieldInfoLayout.SetValue(this, layoutData);
}
改好了,在滚动的过程中,VScroll是没有问题的,可是在HScroll就出问题了,估计是系统会触发OnColumnStateChanged了事件调用了PerformlayoutPrivate方法把布局又重新算了一遍。
而且改了layout后,还有个问题是在edit的时候,在算FirstDisplayRowIndex的时候会出错。
这两个问题都不得而解,所以发贴让大家再讨论一下。
基本情况描述:
在DataGridView最下端加一行合计行,而且这一行是冻结不动行。
探索过程:
1)有人建议用datatable的Rows.Add+Compute来合计,但是无法实现一直在底部可见,而且输入数据的时候也很难处理,是最傻的方法。
2)有人建议用在datagridview CellPainting /RowPostPainting事件往datagridview 底部画线,画值,可是有个严重的问题是,当拖动滚动条的时候会被遮盖住了,也是一种没把最根本问题解决的思路。
3)定义一个自定义控件DataGridViewFooter,能根据DataGridView的列和值自动画表格和统计值,在 DataGridView OnPaint方法里把Footer 画出来,这是一种把根本问题解决的思路,可是难度很大。
4)做用户控件(UserControl),用两个DataGridView来显示,配合VScrollBar来显示滚动,现在本人暂时用这个方法先处理,可是在加载Column的时候很不方便,要自己写代码,浪费时间。
现在重点考虑方法3,通过Reflector窥看修改datagridview难点:
控件首先会触发OnLayout事件,把datagridview里的VScrollBar、HScrollBar、RowsHeader、ColumnHeader、Data这几个区域的位置和大小都算好,主要计算方法是PerformLayoutPrivate里的ComputeLayout,储存这些数据的是DataGridView私有变量layout。
好,明白这里后,本人在OnLayout事件之后,利用.net的反射机制,把加上DataGridViewFooter后的布局数值设置到layout去具体代码如下:
if (base.IsHandleCreated)
{
Type t = this.GetType();
FieldInfo fieldInfoLayout = t.BaseType.GetField("layout", BindingFlags.NonPublic | BindingFlags.Instance);
if (fieldInfoLayout == null) return;
Object layoutData = fieldInfoLayout.GetValue(this);
if (layoutData == null) return;
//reset layout's data and rowheader field rectangle
Type typeLayoutData = layoutData.GetType();
FieldInfo fieldInfoData = typeLayoutData.GetField("Data");
FieldInfo fieldInfoRowHeaders = typeLayoutData.GetField("RowHeaders");
MethodInfo methodInfoComputeVisibleRows = t.BaseType.GetMethod("ComputeVisibleRows", BindingFlags.NonPublic | BindingFlags.Instance);
this._dataclient = (Rectangle)fieldInfoData.GetValue(layoutData);
this._dataclient = new Rectangle(this._dataclient.X, this._dataclient.Y, this._dataclient.Width, this._dataclient.Height-this._datagridviewfooter.Height);
Rectangle rectRowHeader = (Rectangle)fieldInfoRowHeaders.GetValue(layoutData);
rectRowHeader = new Rectangle(rectRowHeader.X, rectRowHeader.Y, rectRowHeader.Width, rectRowHeader.Height - this._datagridviewfooter.Height);
fieldInfoData.SetValue(layoutData, this._dataclient);
fieldInfoRowHeaders.SetValue(layoutData, rectRowHeader);
methodInfoComputeVisibleRows.Invoke(this, null);
fieldInfoLayout.SetValue(this, layoutData);
}
改好了,在滚动的过程中,VScroll是没有问题的,可是在HScroll就出问题了,估计是系统会触发OnColumnStateChanged了事件调用了PerformlayoutPrivate方法把布局又重新算了一遍。
而且改了layout后,还有个问题是在edit的时候,在算FirstDisplayRowIndex的时候会出错。
这两个问题都不得而解,所以发贴让大家再讨论一下。
参考资料: 如果您的回答是从其他地方引用,请表明出处
展开全部
以前也想实现这样的功能,作为合计栏来使用,后来没实现就放弃了,还是在下面增加一列label,宽度与datagridview的列宽一样,用这个来体现合计功能,结果一样很完美,换一种思维不也是很好么?
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
我的想法和: <<回答者: ggyy0516 - 经理 四级 >>一样!
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
用个label。效果出来就行了被
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询