Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何以像素增量滚动DataGridView_C#_Winforms_Scroll_Datagridview_Panel - Fatal编程技术网

C# 如何以像素增量滚动DataGridView

C# 如何以像素增量滚动DataGridView,c#,winforms,scroll,datagridview,panel,C#,Winforms,Scroll,Datagridview,Panel,我最初的方法是将我的DataGridView封装在一个面板内,将其高度设置在面板边界之外,然后更改控制面板的滚动条位置。但是,我刚刚发现DataGridView中的行数将达到2000,这迫使我将DataGridView的大小至少调整为: 65px(行高)x2000=130000px 我的64位计算机上DataGridView控件允许的最大大小为65535。任何人都能想出解决这个问题的办法吗 也许可以将行高设置为1像素,这样所有行在加载时都会变为1像素高。然后假设您知道在DataGridView的

我最初的方法是将我的DataGridView封装在一个面板内,将其高度设置在面板边界之外,然后更改控制面板的滚动条位置。但是,我刚刚发现DataGridView中的行数将达到2000,这迫使我将DataGridView的大小至少调整为:

65px(行高)x2000=130000px


我的64位计算机上DataGridView控件允许的最大大小为65535。任何人都能想出解决这个问题的办法吗

也许可以将行高设置为1像素,这样所有行在加载时都会变为1像素高。然后假设您知道在DataGridView的最大高度中可以看到多少行,您可以确保选择了一行并将其放置在其中。然后,通过循环,您可以将所选行和所选行上方和下方的
x
行的高度设置为65像素。当所选行发生变化时(当用户使用箭头键等),让其将所选行滚动到中心并再次调整行的大小。这是我能想到的解决这个案子的唯一办法

我希望这对你有所帮助

很抱歉,这个要求不是DataGridView的工作方式。你不知道 实际上直接与滚动条交互

以这段代码为例,您唯一可以控制的属性是

您不能将DataGridView行作为分数滚动(例如半行滚动或…按您的需要将更大的粒度向下滚动到像素级别)。

private void按钮1\u单击(对象发送者,事件参数e)
{
var dt=新数据表();
dt.列。添加(“测试”);
var rnd=新随机数();
对于(int i=0;i<10000;i++)
{
var dr=dt.NewRow();
dr[0]=rnd.Next().ToString();
dt.Rows.Add(dr);
}
dataGridView1.DataSource=dt;
}
int i=0;
int lastTopRow=0;
var isRecursive=false;
私有void dataGridView1_滚动(对象发送方,ScrollEventArgs e)
{
如果(可执行)返回;
//尊重每个第20卷的“*渐进*”滚动
如果(i%20==0)
{
lastTopRow++;
}
isRecursive=true;
dataGridView1.FirstDisplayedScrollingRowIndex=lastTopRow;
isRecursive=假;
//边界检查
如果(i>int.MaxValue)i=0;
i++;
}
您可能需要借助屏幕截图(即使用光点),以便 诱使用户认为网格一次滚动一个像素 实际上,这只是一个图像。我不推荐这种方法

另一种方法是使用面板或组框之类的视口,并更改GridView的顶部位置。

private void button1_Click(object sender, EventArgs e)
{
    var dt = new DataTable();
    dt.Columns.Add("test");

    var rnd = new Random();
    for (int i = 0; i < 10000; i++)
    {
        var dr = dt.NewRow();
        dr[0] = rnd.Next().ToString();
        dt.Rows.Add(dr);
    }
    dataGridView1.DataSource = dt;
}

int i = 0;
int lastTopRow = 0;
var isRecursive = false;
private void dataGridView1_Scroll(object sender, ScrollEventArgs e)
{
    if (isRecursive) return;
    //Honor each 20th scroll for "*attempted gradual*" scrolling
    if (i % 20 == 0)
    {
        lastTopRow++;
    }

    isRecursive = true;
    dataGridView1.FirstDisplayedScrollingRowIndex = lastTopRow;
    isRecursive = false;

    //Boundary check
    if (i > int.MaxValue) i = 0;
    i++;
}
除非你想让你的应用程序的用户得到RSI或CTS,否则我看不出如此精确地滚动有什么意义


嗯,不,你不能两全其美。65535像素的大小限制不是人为的,而是操作系统中的硬限制。根本的原因是这个问题。传递的LPARAM参数的值记录为:

如果LOWORD是SB_THUMBPOSITION或SB_THUMBTRACK,则HIWORD指定滚动框的当前位置

HIWORD是值中的高16位,LOWORD是低16位。它只能提供0的范围。。功率(2,16)-1=0..65535。这个限制在其他地方是可见的,如果你在列表框中塞满了超过(65535+可见)个项目,它的行为就会很糟糕。你不能再滚动到底部了


听起来是一个相当糟糕的问题,微软当然应该修复他们软件中如此可怕的限制。但不,这并不是他们的首要任务。与WaitHandle.WaitAny()无法处理包含64个以上项的数组这一看似奇怪的限制不同。这是故意的,他们认为你做错了,而不是他们。而你是,一个期望用户浏览数千行信息的用户界面不是一个非常有用或友好的界面。比如说,从谷歌显示数十万条查询点击的方式中可以得到一个启示。

我不推荐这样做,但首先,除了不把它们都放在DGV的第一位之外;-),是要更改视口中及其周围的所有行大小,但某些行除外。当它们的高度为0时,DGV可能会小得多。听起来很疯狂,也许是这样,-@Anthony为此使用DataGridView没有什么错。它为我提供了方便,可以将数据制表、绑定并格式化外观,但它不能做我需要的一件事。我不是说不使用DataGridView,我的意思是,将它的大小设置为巨大的大小,然后将它放在另一个可滚动控件中,这样你就可以为巨大的DataGridView进行像素级的滚动了,这是在问问题。滚动65次才能到达新行,你一定是在开玩笑!唯一希望这样做的客户是一家推广RSI的保险公司。@JeremyThompson之所以需要这样做,是因为我正在DataGridView上实现flicks,需要通过像素滚动。