namespace DataTablePrettyPrinter { using System; using System.Data; using System.Linq; /// /// An extension class providing utility methods for pretty printing to a string. /// public static class DataColumnExtensions { /// /// Gets the border around the data area of the column. /// /// /// /// The column to pretty print. /// /// /// /// The border around the data area of the column. /// public static Border GetDataBorder(this DataColumn column) { return column.GetExtendedProperty("DataBorder", Border.All); } /// /// Sets the border around the data area of the column. /// /// /// /// The column to pretty print. /// /// /// /// The value to set. /// public static void SetDataBorder(this DataColumn column, Border value) { column.SetExtendedProperty("DataBorder", value); } /// /// Gets the text alignment of the data in this column. /// /// /// /// The column to pretty print. /// /// /// /// Gets the data alignment. /// public static TextAlignment GetDataAlignment(this DataColumn column) { return column.GetExtendedProperty("DataAlignment", TextAlignment.Left); } /// /// Sets the text alignment of the data in this column. /// /// /// /// The column to pretty print. /// /// /// /// The value to set. /// public static void SetDataAlignment(this DataColumn column, TextAlignment value) { column.SetExtendedProperty("DataAlignment", value); } /// /// Gets the formatting method which given a column and row formats the data of the cell into a string. This /// API can be used for arbitrary formatting of induvidual data cells. /// /// /// /// The column to pretty print. /// /// /// /// The method which formats the data cell. /// public static Func GetDataTextFormat(this DataColumn column) { return column.GetExtendedProperty>("DataTextFormat", (c, r) => string.Format("{0}", r[c])); } /// /// Sets the formatting method which given a column and row formats the data of the cell into a string. This /// API can be used for arbitrary formatting of induvidual data cells. /// /// /// /// The column to pretty print. /// /// /// /// The method used to format the data cell which will be called during pretty printing of the table. /// public static void SetDataTextFormat(this DataColumn column, Func value) { column.SetExtendedProperty("DataTextFormat", value); } /// /// Gets the border around the column header area which displays the column names. /// /// /// /// The column to pretty print. /// /// /// /// The border around the column header area. /// public static Border GetHeaderBorder(this DataColumn column) { return column.GetExtendedProperty("HeaderBorder", Border.All); } /// /// Sets the border around the column header area which displays the column names. /// /// /// /// The column to pretty print. /// /// /// /// The value to set. /// public static void SetHeaderBorder(this DataColumn column, Border value) { column.SetExtendedProperty("HeaderBorder", value); } /// /// Gets the text alignment. /// /// /// /// The column to pretty print. /// /// /// /// Gets the column name text alignment. /// public static TextAlignment GetColumnNameAlignment(this DataColumn column) { return column.GetExtendedProperty("ColumnNameAlignment", TextAlignment.Center); } /// /// Sets the text alignment. /// /// /// /// The column to pretty print. /// /// /// /// The value to set. /// public static void SetColumnNameAlignment(this DataColumn column, TextAlignment value) { column.SetExtendedProperty("ColumnNameAlignment", value); } /// /// Gets whether to show the . /// /// /// /// The column to pretty print. /// /// /// /// true if the column name is to be shown; false otherwise. /// public static bool GetShowColumnName(this DataColumn column) { return column.GetExtendedProperty("ShowColumnName", true); } /// /// Sets whether to show the . /// /// /// /// The column to pretty print. /// /// /// /// The value to set. /// public static void SetShowColumnName(this DataColumn column, bool value) { column.SetExtendedProperty("ShowColumnName", value); } /// /// Gets the width (in characters) of this column as it would appear on the pretty printed table. /// /// /// /// The input column. /// /// /// /// The width (in characters) of this column which is retrieved either by user defined value or the aggregate /// maximum width of any row in the table. /// public static int GetWidth(this DataColumn column) { if (column.ExtendedProperties.ContainsKey("Width")) { return (int)column.ExtendedProperties["Width"]; } else { var columnNameLength = 1; if (column.GetShowColumnName()) { columnNameLength = column.ColumnName.Length; } // Linq.Max cannot handle empty sequences if (column.Table.Rows.Count == 0) { return columnNameLength + 2; } else { return Math.Max(columnNameLength, column.Table.Rows.Cast().Max(r => column.GetDataTextFormat().Invoke(column, r).Length)) + 2; } } } /// /// Sets the width (in characters) of this column as it would appear on the pretty printed table. /// /// /// /// The input column. /// /// /// /// The value to set which will be clamped to be at least 1. /// public static void SetWidth(this DataColumn column, int value) { value = Math.Max(1, value); column.SetExtendedProperty("Width", value); } /// /// Gets the beginning X coordinate of the data area of this column. /// /// /// /// The input column. /// /// /// /// The X coordinate of the beginning of the data area. /// internal static int GetDataX1(this DataColumn column) { var columnIndex = column.Table.Columns.IndexOf(column); return column.Table.Columns.Cast().Take(columnIndex).Aggregate(0, (a, c) => a + c.GetWidth() + 1); } /// /// Gets the end X coordinate of the data area of this column. /// /// /// /// The input column. /// /// /// /// The X coordinate of the end of the data area. /// internal static int GetDataX2(this DataColumn column) { return column.GetDataX1() + 1 + column.GetWidth(); } /// /// Gets the beginning Y coordinate of the data area of this column. /// /// /// /// The input column. /// /// /// /// The Y coordinate of the beginning of the data area. /// internal static int GetDataY1(this DataColumn column) { // Account for the top border var y1 = 1; // Account for the title and a rule following the title if (column.Table.GetShowTableName()) { y1 += 2; } // Account for the header and a rule following the header if (column.Table.GetShowColumnHeader()) { y1 += 2; } return y1; } /// /// Gets the end Y coordinate of the data area of this column. /// /// /// /// The input column. /// /// /// /// The Y coordinate of the end of the data area. /// internal static int GetDataY2(this DataColumn column) { return column.GetDataY1() + column.Table.Rows.Cast().Aggregate(0, (a, r) => a + r.GetHeight()); } /// /// Gets an extended property from the with a default value if it does not exist. /// /// /// /// The type of the value to get. /// /// /// /// The column to pretty print. /// /// /// /// The extended property to get. /// /// /// /// The default value to return if the extended property does not exist. /// /// /// /// The value of the extended property if it exists; otherwise. /// internal static T GetExtendedProperty(this DataColumn column, string property, T defaultValue = default) { if (column.ExtendedProperties[property] is T) { return (T)column.ExtendedProperties[property]; } else { return defaultValue; } } /// /// Sets an extended property from the . /// /// /// /// The type of the value to get. /// /// /// /// The column to pretty print. /// /// /// /// The extended property to set. /// /// /// /// The value to set. /// internal static void SetExtendedProperty(this DataColumn column, string property, T value) { column.ExtendedProperties[property] = value; } } }