404 lines
13 KiB
C#
404 lines
13 KiB
C#
namespace DataTablePrettyPrinter
|
|
{
|
|
using System;
|
|
using System.Data;
|
|
using System.Linq;
|
|
|
|
/// <summary>
|
|
/// An extension class providing <see cref="DataColumn"/> utility methods for pretty printing to a string.
|
|
/// </summary>
|
|
public static class DataColumnExtensions
|
|
{
|
|
/// <summary>
|
|
/// Gets the border around the data area of the column.
|
|
/// </summary>
|
|
///
|
|
/// <param name="column">
|
|
/// The column to pretty print.
|
|
/// </param>
|
|
///
|
|
/// <returns>
|
|
/// The border around the data area of the column.
|
|
/// </returns>
|
|
public static Border GetDataBorder(this DataColumn column)
|
|
{
|
|
return column.GetExtendedProperty("DataBorder", Border.All);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the border around the data area of the column.
|
|
/// </summary>
|
|
///
|
|
/// <param name="column">
|
|
/// The column to pretty print.
|
|
/// </param>
|
|
///
|
|
/// <param name="value">
|
|
/// The value to set.
|
|
/// </param>
|
|
public static void SetDataBorder(this DataColumn column, Border value)
|
|
{
|
|
column.SetExtendedProperty("DataBorder", value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the text alignment of the data in this column.
|
|
/// </summary>
|
|
///
|
|
/// <param name="column">
|
|
/// The column to pretty print.
|
|
/// </param>
|
|
///
|
|
/// <returns>
|
|
/// Gets the data alignment.
|
|
/// </returns>
|
|
public static TextAlignment GetDataAlignment(this DataColumn column)
|
|
{
|
|
return column.GetExtendedProperty("DataAlignment", TextAlignment.Left);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the text alignment of the data in this column.
|
|
/// </summary>
|
|
///
|
|
/// <param name="column">
|
|
/// The column to pretty print.
|
|
/// </param>
|
|
///
|
|
/// <param name="value">
|
|
/// The value to set.
|
|
/// </param>
|
|
public static void SetDataAlignment(this DataColumn column, TextAlignment value)
|
|
{
|
|
column.SetExtendedProperty("DataAlignment", value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
///
|
|
/// <param name="column">
|
|
/// The column to pretty print.
|
|
/// </param>
|
|
///
|
|
/// <returns>
|
|
/// The method which formats the data cell.
|
|
/// </returns>
|
|
public static Func<DataColumn, DataRow, string> GetDataTextFormat(this DataColumn column)
|
|
{
|
|
return column.GetExtendedProperty<Func<DataColumn, DataRow, string>>("DataTextFormat", (c, r) => string.Format("{0}", r[c]));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
///
|
|
/// <param name="column">
|
|
/// The column to pretty print.
|
|
/// </param>
|
|
///
|
|
/// <param name="value">
|
|
/// The method used to format the data cell which will be called during pretty printing of the table.
|
|
/// </param>
|
|
public static void SetDataTextFormat(this DataColumn column, Func<DataColumn, DataRow, string> value)
|
|
{
|
|
column.SetExtendedProperty("DataTextFormat", value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the border around the column header area which displays the column names.
|
|
/// </summary>
|
|
///
|
|
/// <param name="column">
|
|
/// The column to pretty print.
|
|
/// </param>
|
|
///
|
|
/// <returns>
|
|
/// The border around the column header area.
|
|
/// </returns>
|
|
public static Border GetHeaderBorder(this DataColumn column)
|
|
{
|
|
return column.GetExtendedProperty("HeaderBorder", Border.All);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the border around the column header area which displays the column names.
|
|
/// </summary>
|
|
///
|
|
/// <param name="column">
|
|
/// The column to pretty print.
|
|
/// </param>
|
|
///
|
|
/// <param name="value">
|
|
/// The value to set.
|
|
/// </param>
|
|
public static void SetHeaderBorder(this DataColumn column, Border value)
|
|
{
|
|
column.SetExtendedProperty("HeaderBorder", value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the <see cref="DataColumn.ColumnName"/> text alignment.
|
|
/// </summary>
|
|
///
|
|
/// <param name="column">
|
|
/// The column to pretty print.
|
|
/// </param>
|
|
///
|
|
/// <returns>
|
|
/// Gets the column name text alignment.
|
|
/// </returns>
|
|
public static TextAlignment GetColumnNameAlignment(this DataColumn column)
|
|
{
|
|
return column.GetExtendedProperty("ColumnNameAlignment", TextAlignment.Center);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the <see cref="DataColumn.ColumnName"/> text alignment.
|
|
/// </summary>
|
|
///
|
|
/// <param name="column">
|
|
/// The column to pretty print.
|
|
/// </param>
|
|
///
|
|
/// <param name="value">
|
|
/// The value to set.
|
|
/// </param>
|
|
public static void SetColumnNameAlignment(this DataColumn column, TextAlignment value)
|
|
{
|
|
column.SetExtendedProperty("ColumnNameAlignment", value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets whether to show the <see cref="DataTable.TableName"/>.
|
|
/// </summary>
|
|
///
|
|
/// <param name="column">
|
|
/// The column to pretty print.
|
|
/// </param>
|
|
///
|
|
/// <returns>
|
|
/// <c>true</c> if the column name is to be shown; <c>false</c> otherwise.
|
|
/// </returns>
|
|
public static bool GetShowColumnName(this DataColumn column)
|
|
{
|
|
return column.GetExtendedProperty("ShowColumnName", true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets whether to show the <see cref="DataTable.TableName"/>.
|
|
/// </summary>
|
|
///
|
|
/// <param name="column">
|
|
/// The column to pretty print.
|
|
/// </param>
|
|
///
|
|
/// <param name="value">
|
|
/// The value to set.
|
|
/// </param>
|
|
public static void SetShowColumnName(this DataColumn column, bool value)
|
|
{
|
|
column.SetExtendedProperty("ShowColumnName", value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the width (in characters) of this column as it would appear on the pretty printed table.
|
|
/// </summary>
|
|
///
|
|
/// <param name="column">
|
|
/// The input column.
|
|
/// </param>
|
|
///
|
|
/// <returns>
|
|
/// 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.
|
|
/// </returns>
|
|
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<DataRow>().Max(r => column.GetDataTextFormat().Invoke(column, r).Length)) + 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the width (in characters) of this column as it would appear on the pretty printed table.
|
|
/// </summary>
|
|
///
|
|
/// <param name="column">
|
|
/// The input column.
|
|
/// </param>
|
|
///
|
|
/// <param name="value">
|
|
/// The value to set which will be clamped to be at least 1.
|
|
/// </param>
|
|
public static void SetWidth(this DataColumn column, int value)
|
|
{
|
|
value = Math.Max(1, value);
|
|
|
|
column.SetExtendedProperty("Width", value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the beginning X coordinate of the data area of this column.
|
|
/// </summary>
|
|
///
|
|
/// <param name="column">
|
|
/// The input column.
|
|
/// </param>
|
|
///
|
|
/// <returns>
|
|
/// The X coordinate of the beginning of the data area.
|
|
/// </returns>
|
|
internal static int GetDataX1(this DataColumn column)
|
|
{
|
|
var columnIndex = column.Table.Columns.IndexOf(column);
|
|
|
|
return column.Table.Columns.Cast<DataColumn>().Take(columnIndex).Aggregate(0, (a, c) => a + c.GetWidth() + 1);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the end X coordinate of the data area of this column.
|
|
/// </summary>
|
|
///
|
|
/// <param name="column">
|
|
/// The input column.
|
|
/// </param>
|
|
///
|
|
/// <returns>
|
|
/// The X coordinate of the end of the data area.
|
|
/// </returns>
|
|
internal static int GetDataX2(this DataColumn column)
|
|
{
|
|
return column.GetDataX1() + 1 + column.GetWidth();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the beginning Y coordinate of the data area of this column.
|
|
/// </summary>
|
|
///
|
|
/// <param name="column">
|
|
/// The input column.
|
|
/// </param>
|
|
///
|
|
/// <returns>
|
|
/// The Y coordinate of the beginning of the data area.
|
|
/// </returns>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the end Y coordinate of the data area of this column.
|
|
/// </summary>
|
|
///
|
|
/// <param name="column">
|
|
/// The input column.
|
|
/// </param>
|
|
///
|
|
/// <returns>
|
|
/// The Y coordinate of the end of the data area.
|
|
/// </returns>
|
|
internal static int GetDataY2(this DataColumn column)
|
|
{
|
|
return column.GetDataY1() + column.Table.Rows.Cast<DataRow>().Aggregate(0, (a, r) => a + r.GetHeight());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets an extended property from the <see cref="DataColumn"/> with a default value if it does not exist.
|
|
/// </summary>
|
|
///
|
|
/// <typeparam name="T">
|
|
/// The type of the value to get.
|
|
/// </typeparam>
|
|
///
|
|
/// <param name="column">
|
|
/// The column to pretty print.
|
|
/// </param>
|
|
///
|
|
/// <param name="property">
|
|
/// The extended property to get.
|
|
/// </param>
|
|
///
|
|
/// <param name="defaultValue">
|
|
/// The default value to return if the extended property does not exist.
|
|
/// </param>
|
|
///
|
|
/// <returns>
|
|
/// The value of the extended property if it exists; <paramref name="defaultValue"/> otherwise.
|
|
/// </returns>
|
|
internal static T GetExtendedProperty<T>(this DataColumn column, string property, T defaultValue = default)
|
|
{
|
|
if (column.ExtendedProperties[property] is T)
|
|
{
|
|
return (T)column.ExtendedProperties[property];
|
|
}
|
|
else
|
|
{
|
|
return defaultValue;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets an extended property from the <see cref="DataColumn"/>.
|
|
/// </summary>
|
|
///
|
|
/// <typeparam name="T">
|
|
/// The type of the value to get.
|
|
/// </typeparam>
|
|
///
|
|
/// <param name="column">
|
|
/// The column to pretty print.
|
|
/// </param>
|
|
///
|
|
/// <param name="property">
|
|
/// The extended property to set.
|
|
/// </param>
|
|
///
|
|
/// <param name="value">
|
|
/// The value to set.
|
|
/// </param>
|
|
internal static void SetExtendedProperty<T>(this DataColumn column, string property, T value)
|
|
{
|
|
column.ExtendedProperties[property] = value;
|
|
}
|
|
}
|
|
}
|