XtraGrid滚轮翻页

滚轮翻页与传动的翻页更为方便,经过本人一番探讨与琢磨终于在XtraGrid的GridView中实现了鼠标滚轮翻页。

我新建了一个组件继承原本的GridControl,在组件中添加了一个ImageList,专门存放一些资源图片。用于实现动态图的效果。

添加一个自定义委托的参数与枚举,委托参数用于传递分页的信息。

    public class PagingEventArgs : EventArgs
    {
        public int PageSize { get; set; }
        public int PageIndex { get; set; }
    }

    public enum LoadState
    { 
        /// <summary>
        /// 就绪
        /// </summary>
        Ready,

        /// <summary>
        /// 正在读取
        /// </summary>
        Loading,

        /// <summary>
        /// 读取完成
        /// </summary>
        Finish
    }

在组件的类里面添加以下字段

        /// <summary>
        /// 页面大小
        /// </summary>
        private int _int_page_size=20;

        /// <summary>
        /// 当前页索引
        /// </summary>
        private int _int_page_index=1;

        /// <summary>
        /// 总记录数
        /// </summary>
        private int _int_record_count;

        /// <summary>
        /// 读取状态 
        /// </summary>
        private LoadState _LodaState_state;

添加以下属性

        /// <summary>
        /// 总记录数
        /// </summary>
        public int RecordCount
        {
            get 
            {
                if (!IsPaging) return 0;
                return _int_record_count; 
            }
            set
            {
                if (!IsPaging) return ;
                _int_record_count = value; 
                //当设置了新的记录总数,自动读取第一页的内容
                if(value>0)
                    gridView_TopRowChanged(this, new EventArgs());

          else
          {
              while (this.MainView.DataRowCount > 0)
                GridView_main_view.DeleteRow(0);
              this.RefreshDataSource();
          }

            }
        }

        /// <summary>
        /// 每次读取的行数
        /// </summary>
        public int PageSize
        {
            get 
            {
                if (!IsPaging) return 0;
                return _int_page_size; 
            }
            set 
            {
                if (!IsPaging) return ;
                _int_page_size = value; 
            }
        }

        /// <summary>
        /// 总页数
        /// </summary>
        private int PageCount
        {
            get 
            {
                if (RecordCount % PageSize == 0)
                    return RecordCount / PageSize;
                return RecordCount / PageSize + 1;
            }
        }

        /// <summary>
        /// Grid
        /// </summary>
        private GridView _GridView_main_view
        {
            get { return (GridView)this.MainView; }
        }

        /// <summary>
        /// 是否启用分页
        /// </summary>
        public bool IsPaging { get; set; }

添加以下委托与事件

        /// <summary>
        /// 内部使用的委托
        /// </summary>
        private delegate void myDelegate();

        /// <summary>
        /// 滚动翻页的委托
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public delegate void ScrollingToPageEventHandler(object sender, PagingEventArgs e);

        /// <summary>
        /// 滚动翻页的事件
        /// </summary>
        public event ScrollingToPageEventHandler OnScrollingToPage;

 

以下则是一些对控件的设置,按照各人喜好可以有所更改。

        /// <summary>
        /// 设置分页栏
        /// </summary>
        private void InitEmbeddedNavigator()
        {this.EmbeddedNavigator.CustomButtons.AddRange(new DevExpress.XtraEditors.NavigatorCustomButton[] {
            new DevExpress.XtraEditors.NavigatorCustomButton(-1, -1, true, false, "", null)});
            this.EmbeddedNavigator.TextStringFormat = "  当前 {1} 行数据  ";
            this.UseEmbeddedNavigator = true;

        }

        /// <summary>
        /// 设置gridView
        /// </summary>
        private void InitGridView()
        { 
            _GridView_main_view.TopRowChanged += new EventHandler(gridView_TopRowChanged);
        }

 

为控件的事件注册以下方法

        private void gridControl_Load(object sender, EventArgs e)
        {
            if (IsPaging)
            {
                _LodaState_state = LoadState.Ready;

                InitEmbeddedNavigator();
                InitGridView();
            }
        }

        private void gridView_TopRowChanged(object sender, EventArgs e)
        {

            lock (this)
            {
                if ( _int_page_index > PageCount || _LodaState_state != LoadState.Ready) return;
            }

            //检查是否到达底部
            if (_GridView_main_view.IsRowVisible(_GridView_main_view.RowCount - 1) == RowVisibleState.Visible||
                _int_page_index==1)
            {

                lock (this)//设置成开始读取状态
                {
                    _LodaState_state = LoadState.Loading;
                }
                Thread thread_load_data = new Thread(new ThreadStart(LoadData));
                Thread thread_change_text = new Thread(new ThreadStart(ChangeLoadingImage));
                thread_change_text.Start();
                thread_load_data.Start();
            }
        }

 

TopRowChanged事件在grid的首行改变了就会触发,类似于滚动条的Scroll事件。这里开了两个线程,第一个线程用于读取数据,第二个线程用于实现动态图。两个线程调用的方法都在下面

        /// <summary>
        /// 读取数据
        /// </summary>
        private void LoadData()
        {
            int top_row_index = 0;
            int focus_index = 0;
            lock (this)
            {
                top_row_index = _GridView_main_view.TopRowIndex;
                focus_index = _GridView_main_view.FocusedRowHandle;

                //执行事件
                if (OnScrollingToPage == null)
                    throw new Exception("OnScrollingToPage can not be null");

                PagingEventArgs e = new PagingEventArgs();
                e.PageIndex = this._int_page_index;
                e.PageSize = this._int_page_size;
                OnScrollingToPage(this,e);
                
            }

            //刷新grid的数据
            if (this.Parent.InvokeRequired)
            {
                this.Parent.Invoke(new myDelegate(delegate
                {
                    _GridView_main_view.TopRowIndex = top_row_index;
                    _GridView_main_view.FocusedRowHandle = focus_index;
           _GridView_main_view.RefreshData();
})); } lock (this) { _LodaState_state = LoadState.Finish;//设置成读取完成状态 } } /// <summary> /// 更替图片 /// </summary> private void ChangeLoadingImage() { int image_index = 0; if (this.Parent.InvokeRequired)//显示loading的gif { this.Parent.Invoke(new myDelegate(delegate { this.EmbeddedNavigator.Buttons.CustomButtons[0].Visible = true; })); } while (true)//循环更替图片实现动态图效果 { lock (this) { if (_LodaState_state != LoadState.Loading)//判定数据是否完成 break; } Thread.Sleep(120); if (image_index == 3) image_index = 0; else image_index++; if (this.Parent.InvokeRequired) { //轮流更换图片实现gif动态图 this.Parent.Invoke(new myDelegate(delegate { this.EmbeddedNavigator.Buttons.CustomButtons[0].ImageIndex = image_index; })); } } if (this.Parent.InvokeRequired)//隐藏loading的gif { this.Parent.Invoke(new myDelegate(delegate { this.EmbeddedNavigator.Buttons.CustomButtons[0].Visible = false; })); } lock (this) { _LodaState_state = 0; _int_page_index++; } }

 

不过这个代码有点问题,当GridControl绑定的数据源有相同实例的子项时,随着RefreshData方法的调用会不停触发TopRowChanged事件,确切的原因还没搞清楚,解决这个问题就是要不去除数据源上相同的实例子项,要不就不调用RefreshData方法。还有更好的办法还请高手们的指点。

 

 

 

posted @ 2012-10-20 11:56  猴健居士  阅读(1775)  评论(2编辑  收藏  举报