65.9K
CodeProject 正在变化。 阅读更多。
Home

自定义 VScrollbar,使 DataGrid 可通过手指滑动

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2010年2月18日

CPOL

2分钟阅读

viewsIcon

25269

downloadIcon

627

一个自定义的 VScrollbar,使 DataGrid 支持手指滑动。

引言

VScrollbar 控件解决了 Compact Framework 中的 DataGrid 无法像 ListViewListBox 那样通过手指滑动进行滚动的的问题。

背景

我感到很惊讶的是 DataGrid 控件不支持手指滑动。也许大多数情况下,如果我们需要这个功能,应该使用 ListView 控件。但是,我需要在当前正在开发的项目中使用这个功能,并且由于我对网格进行了大量的自定义,我无法回到 ListView。我认为我可以自己轻松地添加这个功能到网格中,而且确实如此,这并不难。但是问题在于,无法设置网格的本机滚动条的位置。所以,我有一个可以通过手指滑动滚动的网格,但滚动条的位置不会改变。由于无法以编程方式设置滚动条的位置,我需要“隐藏”滚动条。这就是这个滚动条控件的原因。

Using the Code

使用该控件的代码非常简单。目前,该控件没有无参数构造函数。所以,我们无法进行拖放操作。但是,它真正需要的只是要附加到的 DataGrid 实例和 DataGrid 的数据源。

private void Form1_Load(object sender, EventArgs e)
{
    DataTable dt = GetData();
    var scrollBar = new GridVScrollBar(this.dataGrid1, dt);
    //This line is not needed if you don't need to show the scrollbar
    this.Controls.Add(scrollBar);
}

限制

目前,第二个输入参数需要是 DataTableIList 类型。我认为通过一些额外的代码,可以将其改为 DataTableIEnumerable

private void SetVisibleItems(int startIndex)
{
    object displaySource = new object();
    var endIndex = VisibleRowCount + startIndex;

    if (_controlDataSource is DataTable)
    {
        var sdt = _controlDataSource as DataTable;
        var dt = sdt.Clone();
        for (int i = startIndex; i < endIndex; i++)
        {
            if (i < ItemCount && i >= 0)
            {
                dt.Rows.Add(sdt.Rows[i].ItemArray);
            }
        }
        displaySource = dt;
    }
    else if (_controlDataSource is IList)
    {
        var sdt = _controlDataSource as IList;
        var list = (IList)Activator.CreateInstance(_controlDataSource.GetType());
        for (int i = startIndex; i < endIndex; i++)
        {
            list.Add(sdt[i]);
        }
    }

    _dataGrid.DataSource = displaySource;
    //_dataGrid.Select(0);  
    //Or one could raise an event such as DisplaySourceReady here to 
    //so that any extra can be handled before the grid refreshes
    _dataGrid.Refresh();
}

对于可见窗口相对于行高度较小的网格,我们应该将 EnableAutoScroll 设置为 false。因为自动滚动逻辑效果不佳,这种情况尚未出现。

private void Form1_Load(object sender, EventArgs e)
{
    DataTable dt = GetData();
    var scrollBar = new GridVScrollBar(this.dataGrid1, dt);
    scrollBar.EnableAutoScroll = false;
    this.Controls.Add(scrollBar);
}

未来改进

如果您进行了任何不错的改进,请发布您的代码!

  • 使数据源限制更少。
  • 使控件适用于不仅仅是 DataGrid
  • 改进自动滚动逻辑。这有点困难且耗时。反正切(速度)可能就足够了。

历史

  • 2010 年 2 月 18 日 -- 初稿。
© . All rights reserved.