我有一个非常奇怪的问题,我无法解决这个问题 .

The Problem

在Windows窗体中,我有一个StatusStrip和一个tableLayoutPanel . StatusStrip包含一个标签,该标签将根据单击的行更改其文本 . tableLayoutPanel设置为autoScroll,因为内容大于我的表单大小 .

每行都有不同的控件 . 您可以找到按钮,标签,文本框或复选框 .

我可以根据所选行选择行并更改文本 . 当我向下滚动然后点击表格时出现问题 . 由于某种原因,表单将移动到表中最后选择的控件 .

例如,如果我在文本框内单击,然后向下滚动,在我单击表格行时无法看到文本框 . 表单将自动移动以显示文本框 .

在我看来,由于某种原因,当我更改文本时,它必须重新绘制整个表格,然后它移动到最后选择的控件 .

What Have I tried

  • 将表格移动到面板内 .

  • 将面板移动到另一个面板 .

  • 至于现在,面板被删除,似乎没有必要 .

  • 最初我有6个标签,将它们全部删除以确保它只发生一个 .

  • 如果我不更改文本,但是例如,在Debug中显示一条消息,那么问题就会消失,对我来说这表明问题存在于"change text"事件中 .

  • 编辑:如果我更改了表格内的标签,问题就消失了 . 所以它似乎是与表格状态标签的组合 .

  • 编辑:如果我将自动滚动移动到表单而不是表格 . 然后问题就消失了 . 但这不是我想要的,因为那样,我的状态栏将不会显示,因为它将在按钮上,我需要它保持可见 .

  • 编辑:如果我使用菜单条,问题仍然存在 . 如果我移动状态Stript . 问题仍然存在 .

  • 已编辑:如果我删除了面板并在表单中使用了标签 . 问题依然存在 .

The Code

我会将代码保持在最低限度,并在必要时添加更多代码 .

这是我更新toolStriptStatusLabel的地方:

System::Void updateSelectedRow(int row) {       
    if (row == selectedRow)
        return;
    selectedRow = row;
    Command ^cmd = commandsList[row];
    commandToolStripStatusLabel->Text = cmd->name;
}

这是我的点击事件:

System::Void tableLayoutPanel1_Click(System::Object^  sender, System::EventArgs^  e) {              
    System::Drawing::Point ^point = GetRowColIndex(
        tableLayoutPanel1,
        tableLayoutPanel1->PointToClient(Cursor->Position           
        ));
    updateSelectedRow(point->Y);
}

这是我找到我点击的行的地方:

System::Drawing::Point ^GetRowColIndex(TableLayoutPanel ^tlp, Point point) {
    if (point.X > tlp->Width || point.Y > tlp->Height)
        return nullptr;

    int w = tlp->Width;
    int h = tlp->Height;
    array<int> ^widths = tlp->GetColumnWidths();

    int i;
    for (i = widths->Length - 1; i >= 0 && point.X < w; i--)
        w -= widths[i];
    int col = i + 1;

    array<int> ^heights = tlp->GetRowHeights();
    for (i = heights->Length - 1; i >= 0 && point.Y < h; i--)
        h -= heights[i];

    int row = i + 1;

    return gcnew Point(col, row);

}