/// <summary> /// Gets a control from a position in a TableLayoutPanel. /// Note: when no control was found, each control is checked on it's own because of bugs in the layout engine from Microsoft. /// </summary> /// <typeparam name="TControl">The type of the control.</typeparam> /// <param name="This">This TableLayoutPanel.</param> /// <param name="column">The column.</param> /// <param name="row">The row.</param> /// <returns> /// The control or <c>null</c>. /// </returns> public static TControl GetControlFromPositionFixed <TControl>(this TableLayoutPanel This, int column, int row) where TControl : Control { #if NET35 Debug.Assert(This != null); #else Contract.Requires(This != null); #endif return(This.GetControlFromPositionFixed(column, row) as TControl); }
/// <summary> /// Copies the last row of a This and all controls in it. /// </summary> /// <param name="This">This TableLayoutPanel.</param> /// <param name="controlCallback">The control callback if any, passing targetRow,targetColumn,sourceControl,targetControl.</param> /// <param name="allowSuspendingLayout">if set to <c>true</c> allows suspending the This layout during this process to prevent flickering.</param> public static void CopyLastRow(this TableLayoutPanel This, Action <int, int, Control, Control> controlCallback = null, bool allowSuspendingLayout = true) { #if NET35 Debug.Assert(This != null); #else Contract.Requires(This != null); #endif if (allowSuspendingLayout) { This.SuspendLayout(); } var lastRow = This.RowCount - 1; // add line This.RowCount++; // add style var rowStyle = This.RowStyles[lastRow]; This.RowStyles.Add(new RowStyle(rowStyle.SizeType, rowStyle.Height)); // copy controls var alreadyVisitedControls = new Dictionary <Control, bool>(); for (var i = This.ColumnCount; i > 0;) { --i; var control = This.GetControlFromPositionFixed(i, lastRow); if (control == null || !alreadyVisitedControls.TryAdd(control, true)) { continue; } var newControl = control.Duplicate(); if (controlCallback != null) { controlCallback(lastRow + 1, i, control, newControl); } This.Controls.Add(newControl, i, lastRow + 1); This.SetRowSpan(newControl, This.GetRowSpan(control)); This.SetColumnSpan(newControl, This.GetColumnSpan(control)); } if (allowSuspendingLayout) { This.ResumeLayout(true); } }
/// <summary> /// Gets a value from a control in the given column and row. /// </summary> /// <typeparam name="TControl">The type of the control which should be there.</typeparam> /// <typeparam name="TType">The type of the value we want to read from it.</typeparam> /// <param name="This">This TableLayoutPanel.</param> /// <param name="row">The row in which the control should be.</param> /// <param name="columnIndex">The column in which the control should be.</param> /// <param name="reader">The reader delegate which reads the actual value from the given control and returns it.</param> /// <returns>The value that was found.</returns> public static TType GetColumnValue <TControl, TType>(this TableLayoutPanel This, uint row, int columnIndex, Func <TControl, TType> reader) where TControl : Control { #if NET35 Debug.Assert(This != null); #else Contract.Requires(This != null); #endif if (row >= This.RowCount) { throw new ArgumentOutOfRangeException("row", row, "Not Allowed"); } var control = This.GetControlFromPositionFixed <TControl>(columnIndex, (int)row); if (control == null) { throw new NotSupportedException(); } return(reader(control)); }