在指定的Y坐标处获取DataGridView行

问题描述 投票:1回答:1

问题

我正在尝试将外部垂直滚动条链接到datagridview。我需要一个外部滚动条,因为无论是否有多余的行,我都希望它始终可见。开始时听起来很简单,但是在调整行大小时遇到​​了麻烦。

尝试次数

我试图滚动每行(滚动条的最大值是行数,小的变化是1,大的变化是显示的行数)。由于无法调整行的大小,因此此操作不起作用,因为这会更改显示的行数,进而设置较大的更改,因此拧紧了滚动条。

我得出结论,最好的方法是按像素值滚动。默认DGV行为按行滚动而不是按像素滚动,因此我需要将像素值转换为行索引,以便可以设置FirstDisplayedScrollingRowIndex属性。但是,我正在寻找一种方法可以在特定点获取行。我已经尝试过HitTestInfo,但这似乎仅适用于显示的行,而不适用于看不见的行。

到目前为止,我发现最好的方法是Lambda循环遍历各行,并找出哪一行属于Y坐标。

    Dim Block As Integer = If(DGV.ColumnHeadersVisible, -DGV.ColumnHeadersHeight, 0)
    Dim ScrollToRow As DataGridViewRow = DGV.Rows.Cast(Of DataGridViewRow).FirstOrDefault(Function(x)
                                                                                              Block += x.Height
                                                                                              Return Block >= VSB.Value
                                                                                          End Function)
    DGV.FirstDisplayedScrollingRowIndex = If(ScrollToRow IsNot Nothing, ScrollToRow.Index, 0)

问题

是否缺少我可以通过Y坐标给我一行或其索引的方法?显然,这应该包括当前未显示的行。

或者,关于如何执行此操作的其他建议?

.net datagridview location vertical-scrolling
1个回答
0
投票

下面的静态函数已在带有和不带有可见DataGridView标头的VS-2019 WinForms中进行了测试。像素位置(X,Y)必须相对于控件的客户区域。该函数将在(X,Y)

处生成行和列的(cr,cc)
  • [当像素位置(X,Y)在网格的行标题或列标题中时,它将返回TRUE(我们在网格中),并且对应的行(cr)或列(cc)坐标返回-1 。
  • 当像素位置(X,Y)在网格的数据部分内部时,它还将返回TRUE并从(0,0)开始提供(cr,cc)。

  • [当指定像素在网格区域之外时,此函数将产生FALSE。

问题的语言未标记,因此我使用C#而不是Basic提供函数。

    private static bool FindPixelPositionInGrid(DataGridView dg, int X, int Y, out int cr, out int cc)
    {
        int rblck = dg.ColumnHeadersVisible ? dg.ColumnHeadersHeight : 0;
        bool foundcr = false;
        cc = cr = -1;
        foreach (DataGridViewRow r in dg.Rows)
        {
            if (rblck > Y) break;
            rblck += r.Height; cr++;
        }
        if (rblck > Y)
        {
            cc = -1;
            var cblck = dg.RowHeadersVisible ? dg.RowHeadersWidth : 0;
            foreach (DataGridViewColumn c in dg.Columns)
            {
                if (cblck > X)
                {
                    foundcr = true;
                    break;
                }
                cblck += c.Width; cc++;
            }
            if (cblck > X) foundcr = true;
        }
        return foundcr;
    }
© www.soinside.com 2019 - 2024. All rights reserved.