问题
我正在尝试将外部垂直滚动条链接到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坐标给我一行或其索引的方法?显然,这应该包括当前未显示的行。
或者,关于如何执行此操作的其他建议?
下面的静态函数已在带有和不带有可见DataGridView标头的VS-2019 WinForms中进行了测试。像素位置(X,Y)必须相对于控件的客户区域。该函数将在(X,Y)
处生成行和列的(cr,cc)当像素位置(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;
}