C#:使用 1 个 ScrollBar 滚动 2 个控件

C#: Scroll 2 Controls with 1 ScrollBar

我有一个 DataGridView 控件和一个 Panel 控件并排放置,高度相同,并且它们都有一个可滚动到相同距离的垂直滚动条。 我要实现的是,我控制DataGridView上的滚动条,每次将Panel上的滚动条移动相同的度数。

我发现了一些例子,其中两个控件都是 DataGridView,但在我的例子中,一个是 Panel。我尝试了以下方法:

//Inside a for loop
myDGV[i].Scroll += (sender, e) => {
    if(e.ScrollOrientation == ScrollOrientation.VerticalScroll)
    {
        int val = myDGV[i].FirstDisplayedScrollingRowIndex; //Error on this line
        myPanel[i].VerticalScroll.Value = val;
    }
};

但是报错:

IndexOutOfRangeException was unhandled.
Index was outside the bounds of the array.

我还找到了 Using one scroll bar to control two DataGridView 并尝试了以下操作:

//This is also inside a for loop
myDGV[i].Scroll += (sender, e) => {
    myPanel[i].VerticallScrollBar.Value = e.NewValue;
};

但它给了我同样的错误。 我每个都有 4 个实例(DataGridViewPanel,每个 i 对应于彼此的实例。Panel 的声明正确,但我我不确定为什么会收到此错误。

有人可以帮忙吗?

您应该在代码中收到有关 "Access to modified closure" 关于在委托中使用变量 i 的警告。

发生的事情是您的委托正在使用局部变量 i,它很可能在引发事件之前更改了它的值(可能比您的数组长度多 1)。此外,所有事件都将使用完全相同的 i 值。

答案是在 for 循环中创建一个新的整数变量,初始化为 i 的当前值。确保在添加委托后不要修改此整数。所有数据网格视图都将使用它们自己的具有正确值的变量副本。

尝试以下解决方案:

for (int i = 0; i < myDGV.Length; i++)
{
    int ii = i;

    myDGV[i].Scroll += (sender, e) => {
        if(e.ScrollOrientation == ScrollOrientation.VerticalScroll)
        {
            int val = myDGV[ii].FirstDisplayedScrollingRowIndex;
            myPanel[ii].VerticalScroll.Value = val;
        }
    };
}