private void RecalculateColumns(TablePanelRow requestor) { if (this.columnsWidthsPerRow.Count != 0) { int NumberOfColumns = this.columnsWidthsPerRow.Max(entry => entry.Value.Length); double[] ColumnWidths = new double[NumberOfColumns]; for (int Index = 0; Index < NumberOfColumns; Index++) { // ReSharper disable AccessToModifiedClosure ColumnWidths[Index] = this.columnsWidthsPerRow.Max(entry => Index < entry.Value.Length ? entry.Value[Index] : 0); // ReSharper restore AccessToModifiedClosure } if (ColumnWidths.HasEqualValue(this.columnWidths, (v1, v2) => Math.Abs(v1 - v2) < 0.0001) == false) { this.columnWidths = ColumnWidths; this.rowsToLayout.Clear(); this.rowsToLayout.AddRange(this.columnsWidthsPerRow.Keys); } //Row will already be layouted with current values -> remove from re-layout list this.rowsToLayout.Remove(requestor); } else { this.columnWidths = new double[0]; } }
internal void Remove(TablePanelRow tablePanelRow) { if (this.columnsWidthsPerRow.ContainsKey(tablePanelRow)) { this.columnsWidthsPerRow.Remove(tablePanelRow); } this.RecalculateColumns(null); }
internal void UpdateColumnWidths(TablePanelRow tablePanelRow, ref double[] columnWidths) { if (this.columnsWidthsPerRow.ContainsKey(tablePanelRow)) { this.columnsWidthsPerRow.Remove(tablePanelRow); } this.columnsWidthsPerRow.Add(tablePanelRow, (double[])columnWidths.Clone()); //Clone!! Arrays are per-ref! this.RecalculateColumns(tablePanelRow); Array.Copy(this.columnWidths, columnWidths, columnWidths.Length); }
/// <summary> /// When overridden in a derived class, positions child elements and determines a size for a <see cref="T:System.Windows.FrameworkElement"/> derived class. /// </summary> /// <returns> /// The actual size used. /// </returns> /// <param name="finalSize">The final area within the parent that this element should use to arrange itself and its children.</param> protected override Size ArrangeOverride(Size finalSize) { foreach (UIElement Child in this.Children) { int Column = TablePanelRow.GetColumn(Child); Rect ChildRect = new Rect( Math.Min(this.columnOffsets[Column], finalSize.Width), 0, Math.Min(this.columnWidths[Column], finalSize.Width - this.columnOffsets[Column]), finalSize.Height); Child.Arrange(ChildRect); } return(finalSize); }
/// <summary> /// When overridden in a derived class, measures the size in layout required for child elements and determines a size for the <see cref="T:System.Windows.FrameworkElement"/>-derived class. /// </summary> /// <returns> /// The size that this element determines it needs during layout, based on its calculations of child element sizes. /// </returns> /// <param name="availableSize">The available size that this element can give to child elements. Infinity can be specified as a value to indicate that the element will size to whatever content is available.</param> protected override Size MeasureOverride(Size availableSize) { this.UpdateTablePanelRoot(); this.UpdateMargin(); int LastColumnIndex = 0; foreach (UIElement Child in this.Children) { int Column = TablePanelRow.GetColumn(Child); LastColumnIndex = Math.Max(LastColumnIndex, Column); Child.Measure(availableSize); } double[] ColumnWidths = new double[LastColumnIndex + 1]; this.measuredHeight = 0; foreach (UIElement Child in this.Children) { int Column = TablePanelRow.GetColumn(Child); Size DesiredSize = Child.DesiredSize; this.measuredHeight = Math.Max(this.measuredHeight, DesiredSize.Height); ColumnWidths[Column] = Math.Max(ColumnWidths[Column], DesiredSize.Width); } //Add the offset to the first cell ColumnWidths[0] += this.margin; // Update Column Widths and retrieve the accumulated ones this.panelRoot.UpdateColumnWidths(this, ref ColumnWidths); //Subtract the offset again to have the layout values ColumnWidths[0] -= this.margin; //Remember for arrange this.columnWidths = ColumnWidths; //Calculate cell offsets from widths for arrange this.columnOffsets = new double[ColumnWidths.Length]; double ColumnOffset = 0; for (int Index = 0; Index < ColumnWidths.Length; Index++) { this.columnOffsets[Index] = ColumnOffset; ColumnOffset += ColumnWidths[Index]; } Size NeededSize = new Size(ColumnWidths.Sum(), this.measuredHeight); return(NeededSize); }