This example assumes there is a form that has a TableLayoutPanel with a vertical and horizontal scroll bar.
The form can be resized and when it is the TableLayoutPanel is re-created to only include what is visible.
This means that only the controls that can be seen are created and makes creating and updating it as fast as possible.
(IBEX library has ready made form with this)
For the TableLayoutPanel
Name Table1
Anchor Top, Bottom, Left, Right
AutoScroll False
AutoSize False
For the horizontal scroll bar
Name TableHozScrollBar1
Anchor Bottom, Left, Right
For the vertical scroll bar
Name TableVertScrollBar1
Anchor Top, Bottom, Right
Create these in the class
//GLOBAL VARAIBLES
private: int TotalNumOfColumns;
private: int TotalNumOfRows;
private: int NumOfColumnsShown;
private: int NumOfRowsShown;
private: int ShowingStartColumnIndex;
private: int ShowingStartRowIndex;
private: array<System::Windows::Forms::TextBox^, 2> ^txtGridBoxes;
In the form load event
//CREATE THE TABLE GRID
TotalNumOfColumns = 150;
TotalNumOfRows = 150;
ShownStartColumnIndex = 0;
ShownStartRowIndex = 0;
EventArgs ^MyArgs = gcnew EventArgs();
frmGroupSetup_ResizeEnd(this, MyArgs); //Trigger the rezize event
These are the functions
//*********************************
//*********************************
//********** FORM RESIZE **********
//*********************************
//*********************************
private: System::Void frmGroupSetup_Resize(System::Object^ sender, System::EventArgs^ e)
{
const int ColumnsWidth = 100; //Set required columns width
const int RowsHeight = 20; //Set required columns height
int Count;
int Column;
int Row;
//---------------------------------------------------------------------------
//----- CALCULATE HOW MANY ROWS AND COLUMNS WE CAN FIT INTO WINDOW SIZE -----
//---------------------------------------------------------------------------
NumOfColumnsShown = (this->Width - 20) / ColumnsWidth; //Subtract width of other items on form.
NumOfColumnsShown++; //We need 1 extra colum to act as the variable size column on the right
NumOfRowsShown = (this->Height - 80) / RowsHeight; //Subtract height of other items on form.
NumOfRowsShown++; //We need 1 extra row to act as the variable size column on the bottom
//Stop re-drawing while we update contents
this->SuspendLayout();
Table1->SuspendLayout();
//--------------------------------------------
//----- REMOVE THE EXISTING CONTROLS ---------
//--------------------------------------------
while (Table1->Controls->Count)
Table1->Controls->RemoveAt(0);
//-----------------------------
//----- RE-SIZE THE TABLE -----
//-----------------------------
//Remove existing styles so we can re-create
while (Table1->ColumnStyles->Count)
Table1->ColumnStyles->RemoveAt(0);
while (Table1->RowStyles->Count)
Table1->RowStyles->RemoveAt(0);
Table1->ColumnCount = NumOfColumnsShown;
Table1->RowCount = NumOfRowsShown;
for (Count = 0; Count < NumOfColumnsShown; Count++)
Table1->ColumnStyles->Add(gcnew System::Windows::Forms::ColumnStyle(System::Windows::Forms::SizeType::Absolute, ColumnsWidth));
for (Count = 0; Count < NumOfRowsShown; Count++)
Table1->RowStyles->Add(gcnew System::Windows::Forms::RowStyle(System::Windows::Forms::SizeType::Absolute, RowsHeight));
//----------------------------
//----- ADD THE CONTROLS -----
//----------------------------
this->txtGridBoxes = gcnew array<System::Windows::Forms::TextBox^, 2>(NumOfColumnsShown, NumOfRowsShown);
for (Column = 0; Column < NumOfColumnsShown; Column++)
{
for (Row = 0; Row < NumOfRowsShown; Row++)
{
this->txtGridBoxes[Column, Row] = (gcnew System::Windows::Forms::TextBox());
this->txtGridBoxes[Column, Row]->Margin = System::Windows::Forms::Padding(0, 0, 0, 0);
this->txtGridBoxes[Column, Row]->BorderStyle = System::Windows::Forms::BorderStyle::FixedSingle;
this->txtGridBoxes[Column, Row]->Dock = System::Windows::Forms::DockStyle::Fill;
this->txtGridBoxes[Column, Row]->ReadOnly = true;
Table1->Controls->Add(this->txtGridBoxes[Column, Row], Column, Row);
}
}
//----------------------------------
//----- UPDATE THE SCROLL BARS -----
//----------------------------------
//----- HORIZONTAL -----
TableHozScrollBar1->Minimum = 0;
if (ShowingStartColumnIndex > (TotalNumOfColumns - NumOfColumnsShown))
{
ShowingStartColumnIndex = (TotalNumOfColumns - NumOfColumnsShown) + 1;
if (ShowingStartColumnIndex < 0)
ShowingStartColumnIndex = 0;
if (ShowingStartColumnIndex >= TotalNumOfColumns)
ShowingStartColumnIndex = TotalNumOfColumns - 1;
TableHozScrollBar1->Value = ShowingStartColumnIndex;
}
if ((NumOfColumnsShown > 1) && (TotalNumOfColumns > NumOfColumnsShown))
TableHozScrollBar1->LargeChange = NumOfColumnsShown - 2;
else
TableHozScrollBar1->LargeChange = 1;
if (TotalNumOfColumns > NumOfColumnsShown)
TableHozScrollBar1->Maximum = (TotalNumOfColumns - NumOfColumnsShown) + TableHozScrollBar1->LargeChange;
else
TableHozScrollBar1->Maximum = 0;
//----- VERTICAL -----
TableVertScrollBar1->Minimum = 0;
if (ShowingStartRowIndex > (TotalNumOfRows - NumOfRowsShown))
{
ShowingStartRowIndex = (TotalNumOfRows - NumOfRowsShown) + 1;
if (ShowingStartRowIndex < 0)
ShowingStartRowIndex = 0;
if (ShowingStartRowIndex >= TotalNumOfColumns)
ShowingStartRowIndex = TotalNumOfColumns - 1;
TableVertScrollBar1->Value = ShowingStartRowIndex;
}
if ((NumOfRowsShown > 1) && (TotalNumOfRows > NumOfRowsShown))
TableVertScrollBar1->LargeChange = NumOfRowsShown - 2;
else
TableVertScrollBar1->LargeChange = 1;
if (TotalNumOfRows > NumOfRowsShown)
TableVertScrollBar1->Maximum = (TotalNumOfRows - NumOfRowsShown) + TableVertScrollBar1->LargeChange;
else
TableVertScrollBar1->Maximum = 0;
//-------------------------------------
//----- UPDATE THE DISPLAYED DATA -----
//-------------------------------------
UpdateTableGridData();
Table1->ResumeLayout();
this->ResumeLayout();
}
//********************************************************
//********************************************************
//********** GRID HORIZONTAL SCROLL BAR CHANGED **********
//********************************************************
//********************************************************
private: System::Void TableHozScrollBar1_ValueChanged(System::Object^ sender, System::EventArgs^ e)
{
if (TableHozScrollBar1->Value < TotalNumOfColumns)
ShowingStartColumnIndex = TableHozScrollBar1->Value;
else
ShowingStartColumnIndex = TotalNumOfColumns - 1;
UpdateTableGridData();
}
//******************************************************
//******************************************************
//********** GRID VERTICAL SCROLL BAR CHANGED **********
//******************************************************
//******************************************************
private: System::Void TableVertScrollBar1_ValueChanged(System::Object^ sender, System::EventArgs^ e)
{
if (TableVertScrollBar1->Value < TotalNumOfRows)
ShowingStartRowIndex = TableVertScrollBar1->Value;
else
ShowingStartRowIndex = TotalNumOfRows - 1;
UpdateTableGridData();
}
//***********************************************
//***********************************************
//********** UPDATE DATA IN TABLE GRID **********
//***********************************************
//***********************************************
private: void UpdateTableGridData(void)
{
int Column;
int Row;
String ^NewText;
Table1->SuspendLayout();
for (Column = 0; Column < NumOfColumnsShown; Column++)
{
for (Row = 0; Row < NumOfRowsShown; Row++)
{
if (
((Column + ShowingStartColumnIndex) < TotalNumOfColumns) &&
((Row + ShowingStartRowIndex) < TotalNumOfRows)
)
{
//SET CELL CONTENTS
NewText = Convert::ToString(Column + ShowingStartColumnIndex) + "," + Convert::ToString(Row + ShowingStartRowIndex);
if (this->txtGridBoxes[Column, Row]->Text != NewText)
this->txtGridBoxes[Column, Row]->Text = NewText;
this->txtGridBoxes[Column, Row]->BackColor = System::Drawing::SystemColors::Control;
}
else
{
//UNUSED CELL
NewText = ""; //Unused end of column or end of row text box - blank
if (this->txtGridBoxes[Column, Row]->Text != NewText)
this->txtGridBoxes[Column, Row]->Text = NewText;
this->txtGridBoxes[Column, Row]->BackColor = System::Drawing::SystemColors::Control;
}
}
}
Table1->ResumeLayout();
}
Feel free to comment if you can add help to this page or point out issues and solutions you have found. I do not provide support on this site, if you need help with a problem head over to stack overflow.