using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; namespace TBF { /// /// Data types and orientation of the table layout panel attached data. /// public enum Arrangement { RowOfIntegers, RowOfDoubles, RowOfStrings, ColumnOfIntegers, ColumnOfDoubles, ColumnOfStrings, } /// /// This class represents TextBox controls and data modified by them /// that are attached to (=displayed inside) a TableLayoutPanel control. /// public class AttachedTextBoxes { /// /// Private fields /// int count; /// Number of attached TextBoxes / cells Arrangement arngmnt; /// Type of attachemnt (see above) bool isRow; /// true if it is a row TextBox[] textBoxes; /// TextBox controls to be aded to TableLayoutPanel int[] intData; /// integer data | double[] doubleData; /// double data |-> one of these three arrays is used string[] stringData; /// string data | /// /// Constructor, which creates TextBox controls and adds them to the table layout panel. /// public AttachedTextBoxes(TableLayoutPanel tblLtPnl, Arrangement arngmnt, int firstColumn, int firstRow, int size) { this.count = size; this.arngmnt = arngmnt; isRow = (arngmnt == Arrangement.RowOfIntegers || arngmnt == Arrangement.RowOfDoubles || arngmnt == Arrangement.RowOfStrings); textBoxes = new TextBox[count]; intData = new int[count]; doubleData = new double[count]; stringData = new string[count]; for (int i = 0; i < count; i++) { textBoxes[i] = new TextBox(); /// Crete a new TextBox control if (isRow) { tblLtPnl.Controls.Add(textBoxes[i], firstColumn + i, firstRow); } else { tblLtPnl.Controls.Add(textBoxes[i], firstColumn, firstRow + i); } } } /// /// Attached data array size /// public int Count { get { return count; } } /// /// Indexer returning a TextBox /// /// Index /// TextBox object reference public TextBox this[int index] { get { if (index < 0 || index >= count) { return null; } else { return textBoxes[index]; } } } /// /// Retrieves data from the controls or detects a format error. /// Wrong format in a cell interrupts data retrieving, so when the first control /// contains data with wrong format, no data are retrieved at all. /// /// true if all data have correct format public bool ValidateData() { switch (arngmnt) { case Arrangement.RowOfIntegers: case Arrangement.ColumnOfIntegers: for (int i = 0; i < count; i++) { if (!Int32.TryParse(textBoxes[i].Text, out intData[i])) return false; } return true; case Arrangement.RowOfDoubles: case Arrangement.ColumnOfDoubles: for (int i = 0; i < count; i++) { if (!Double.TryParse(textBoxes[i].Text, out doubleData[i])) return false; } return true; case Arrangement.RowOfStrings: case Arrangement.ColumnOfStrings: default: return true; } } /// /// The following three methods provide initialization of controls with original data. /// public void SetData(int index, int value) { if (index < 0 || index >= count) return; intData[index] = value; textBoxes[index].Text = value.ToString(); } public void SetData(int index, double value) { if (index < 0 || index >= count) return; doubleData[index] = value; textBoxes[index].Text = value.ToString(); } public void SetData(int index, string value) { if (index < 0 || index >= count) return; stringData[index] = value; textBoxes[index].Text = value; } /// /// The following three methods provide retrieving data from controls. /// ValidateData() must be called first. The return value must be true. /// public int GetIntData(int index) { if (index < 0 || index >= count) return 0; return intData[index]; } public double GetDoubleData(int index) { if (index < 0 || index >= count) return 0; return doubleData[index]; } public string GetStringData(int index) { if (index < 0 || index >= count) return null; return textBoxes[index].Text; } } }