首 页 | 新 闻 | 技术中心 | 第二书店 | 《程序员》 | 《开发高手》 | 社 区 | 黄 页 | 人 才
移 动专 题SUNIBM微 软微 创精 华Donews人 邮
我的技术中心 
我的分类 我的文档
全部文章 发表文章
专栏管理 使用说明



 RSS 订阅 
最新文档列表
Windows/.NET
.NET  (rss)    
Visual C++  (rss)    
Delphi  (rss)    
Visual Basic  (rss)    
ASP  (rss)    
JavaScript  (rss)    
Java/Linux
Java  (rss)    
Perl  (rss)    
综合
其他开发语言  (rss)    
文件格式  (rss)    
企业开发
游戏开发  (rss)    
网站制作技术  (rss)    
数据库
数据库开发  (rss)    
软件工程
其他  (rss)    

积极原创作者 
tellmenow (22)
cutemouse (22)
softj (78)
iiprogram (69)
qdzx2008 (50)
goodboy1881 (14)
wangchinaking (58)
fancyhf (1)
harrymeng (41)
yjz0065 (113)
CSDN - 文档中心 - .NET 阅读:7794   评论: 9    参与评论
标题   如何同步滚动两个相同的DataGrid     选择自 cuike519 的 Blog
关键字   DataGrid,Scroll,同步
出处  

如何同步滚动两个相同的DataGrid

       昨天在CSDN上看到有人高分(100)问这个问题,不忧心中有些痒痒,仔细看了看问题,其实也是我很久以前就像做的一件事情了,今天刚好是周末回家研究一下,有些收获,拿出来和大家分享。

问题描述:在WinForm中如何同步滚动两个DataGrid

问题分析:拿到这个首先想到的就是重写Scroll方法,可是想想工作量有些大,所以想在Form级别上做做手脚,可是屡试不成功(在网上听说有实现的不过没有见到)。无奈之下只好看看能不能从DataGrid下手,看看DataGrid的成员列表可以看到这样两个保护性的方法:

GridHScrolled                       Listens for the horizontal scrollbar's scroll event.

GridVScrolled                       Listens for the vertical scrollbar's scroll event.

很显然这个两个监听滚动条事件的方法,要得就是它,微软真是太好了(心中暗喜)。好了那现在就开始些我们自己的DataGrid吧。首先需要创建一个解决方案,其中有两个工程,一个Windows控件库项目和WinForm项目,前者是我们的写的DataGrid控件后者则是测试控件的工程。创建Windows用户空间会有一个默认的类,删了或者修改他的名字为crlDataGrid(你自己随便叫好了)。我们修改它的继承关系,让他从DataGrid继承。如下所示:

public class CrlDataGrid : System.Windows.Forms.DataGrid

这样我们就可以用我们自己的DataGrid公开上面提到的两个方法了。如下所示:

public void crlGridVScrolled(object sender,ScrollEventArgs e){

       this.GridVScrolled(sender,e);

    }

    public void crlGridHScrolled(object sender,ScrollEventArgs e){

       this.GridHScrolled(sender,e);

}

到此,我们的控件就完成了。其实很简单就是公开了那两个原来隐藏的方法。

 

接下来就是测试项目:我们新建一个WinForm工程。首先我们需要引用我们自己的DataGrid控件,方法如下:在工具箱里使用鼠标右键选择添加/移除项,使用浏览找到我们刚才工程所在目录下面的dll之后添加到工具箱里。用如下的方法把数据绑定到我们自定义个DataGrid上面:

SqlConnection conn = new SqlConnection("server=192.192.192.1;database=northwind;uid=sa;pwd=;");

       SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM Orders",conn);

       DataSet ds = new DataSet();

       da.Fill(ds);

       this. grdSource.DataSource = ds.Tables[0].DefaultView;

    this. grdAim.DataSource = ds.Tables[0].DefaultView;

其中grdSourcegrdAim是两个自定义DataGrid,我们要做的就是当第一个DataGridgrdSource)滚动的时候第二个也以相同的方式滚动。

private CrlDataGrid.CrlDataGrid grdSource;

    private CrlDataGrid.CrlDataGrid grdAim;

下面我们要做的是实现垂直方向的同步我们申明两个VscrollBar对象,为了也可以横向的拖动,我们还声明两个水平的滚动条对象。

VScrollBar m_SourceVScroll;

    VScrollBar m_AimVScroll;

 

HScrollBar m_AimHScroll;

    HScrollBar m_SourceHScroll;

我们将在两个自定义DataGrid中找到他们对应的滚动条对象,同时给这些滚动条的事件压入堆中,同时为他们添加事件处理程序,代码如下:

       public void addEventHandler(){

           foreach(Control ctrl in this.grdSource.Controls){

              if(ctrl.GetType().Name == "VScrollBar"){

                  this.m_SourceVScroll = (VScrollBar)ctrl;

                  break;

              }

           }

 

           foreach(Control ctrl in this.grdAim.Controls){

              if(ctrl.GetType().Name == "VScrollBar"){

                  this.m_AimVScroll = (VScrollBar)ctrl;

                  break;

              }

           }

 

           this.m_SourceVScroll.Scroll +=new ScrollEventHandler(m_SourceVScroll_Scroll);

           this.m_AimVScroll.Scroll +=new ScrollEventHandler(m_AimVScroll_Scroll);

 

           //================== 添加水平 ======================

           foreach(Control ctrl in this.grdSource.Controls){

              if(ctrl.GetType().Name == "HScrollBar"){

                  this.m_SourceHScroll = (HScrollBar)ctrl;

                  break;

              }

           }

 

           foreach(Control ctrl in this.grdAim.Controls){

              if(ctrl.GetType().Name == "HScrollBar"){

                  this.m_AimHScroll = (HScrollBar)ctrl;

                  break;

              }

           }

 

           this.m_AimHScroll.Scroll +=new ScrollEventHandler(m_AimHScroll_Scroll);

           this.m_SourceHScroll.Scroll +=new ScrollEventHandler(m_SourceHScroll_Scroll);

 

}

 

接下来我们要在构造函数中调用这个方法如下所示:

public Form1(){

           //

           // Windows 窗体设计器支持所必需的

           //

           InitializeComponent();

           this.addEventHandler();

    }

最后就是添加事件处理函数如下所示:

private void m_SourceVScroll_Scroll(object sender, ScrollEventArgs e) {

           this.m_AimVScroll.Value = this.m_SourceVScroll.Value;

           this.grdAim.crlGridVScrolled(sender,e);

 

       }

 

       private void m_AimVScroll_Scroll(object sender, ScrollEventArgs e) {

           this.m_SourceVScroll.Value = this.m_AimVScroll.Value;

           this.grdSource.crlGridVScrolled(sender,e);

       }

 

       private void m_AimHScroll_Scroll(object sender, ScrollEventArgs e) {

           this.m_SourceHScroll.Value = this.m_AimHScroll.Value;

           this.grdSource.crlGridHScrolled(sender,e);

       }

 

       private void m_SourceHScroll_Scroll(object sender, ScrollEventArgs e) {

           this.m_AimHScroll.Value = this.m_SourceHScroll.Value;

           this.grdAim.crlGridHScrolled(sender,e);

 

       }

上面分别是水平滚动和垂直滚动的事件处理程序。

到此为止这种两个DataGrid的同步就完成了,编译运行可以通过同时也达到了预期的目的!

文章写的匆忙希望网友们批评指正,可以留言也可以来信wu_jian830@hotmail.com。需要源码的也可以联系我!


相关文章
对该文的评论
hachongzi ( 2003-12-17)
有用乎
cuike519 ( 2003-12-09)
to rt: I really sorry for you! but I think it is important for some people!
hfayga ( 2003-12-09)
支持交流
rt ( 2003-12-08)
WINFORM上的同步还需要拿来说?!
fking22 ( 2003-12-08)
还以为是web上的同步滚动,唉……
web上好像没法捕获客户端点击scrollbar的,要实现可真难。