using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.ComponentModel;
using System.IO;
namespace DynamicDataViewControl
{
public enum DataSeparator { SingleBreak, DoubleBreack, SingleHorizontalLine, DoubleHorizontalLine }
public partial class DynamicDataView : global::System.Web.UI.UserControl
{
#region Properties
private List<string> _rowHeaders = null;
public List<string> RowHeaders
{
get { return _rowHeaders; }
set { _rowHeaders = value; }
}
private List<string> _columnHeaders = null;
public List<string> ColumnHeaders
{
get { return _columnHeaders; }
set { _columnHeaders = value; }
}
private int _maximumColumnsInRow = 10;
/// <summary>
/// Default Value is 10
/// </summary>
public int MaximumColumnsInRow
{
get { return _maximumColumnsInRow; }
set { _maximumColumnsInRow = value; }
}
private DataSeparator _dataDivider = DataSeparator.SingleBreak;
public DataSeparator DataDivider
{
get { return _dataDivider; }
set { _dataDivider = value; }
}
private string _headerCssClass = string.Empty;
public string HeaderCssClass
{
get { return _headerCssClass; }
set { _headerCssClass = value == null ? string.Empty : value; }
}
private string _itemCssClass = string.Empty;
public string ItemCssClass
{
get { return _itemCssClass; }
set { _itemCssClass = value == null ? string.Empty : value; }
}
private string _alternativeItemCssClass = string.Empty;
public string AlternativeItemCssClass
{
get { return _alternativeItemCssClass; }
set { _alternativeItemCssClass = value == null ? string.Empty : value; }
}
private string _tableCssClass = string.Empty;
public string TableCssClass
{
get { return _tableCssClass; }
set { _tableCssClass = value == null ? string.Empty : value; }
}
private double _sumOfGrandTotals = 0;
public double SumOfGrandTotals
{
get { return _sumOfGrandTotals; }
}
public bool IsSumOfGrandTotalsShow { get; set; }
private Dictionary<string, Dictionary<string, string>> _rowSetDataSource = null;
/// <summary>
/// <typeparamref name="Represents Dictionary Keys are RowSetHeaderNames and Values are Dictionary.
/// Values of Dictionary Represents Key as ColumnNames and Value as RowSet Column Data"/>
/// </summary>
public Dictionary<string, Dictionary<string, string>> RowSetDataSource
{
get { return _rowSetDataSource; }
set { _rowSetDataSource = value; }
}
private Dictionary<string, List<string>> _simpleDataSource = null;
/// <summary>
/// <typeparamref name="Represents Dictionary Simple Data Format that Key as Column Name and Value as Column Value"/>
/// </summary>
public Dictionary<string, List<string>> SimpleDataSource
{
get { return _simpleDataSource; }
set { _simpleDataSource = value; }
}
private bool _isSimpleData = false;
public bool IsSimpleData
{
get { return _isSimpleData; }
set { _isSimpleData = value; }
}
private bool _isColumnTotals = false;
public bool IsColumnTotals
{
get { return _isColumnTotals; }
set { _isColumnTotals = value; }
}
private bool _isRowTotals = false;
public bool IsRowTotals
{
get { return _isRowTotals; }
set { _isRowTotals = value; }
}
private bool _isGrandTotal = false;
public bool IsGrandTotal
{
get { return _isGrandTotal; }
set { _isGrandTotal = value; }
}
private List<string> _startEndColumnColors = null;
public List<string> StartEndColumnColors
{
get { return _startEndColumnColors; }
set { _startEndColumnColors = value; }
}
private string _rowHeadersTitle = string.Empty;
public string RowHeadersTitle
{
get { return _rowHeadersTitle; }
set { _rowHeadersTitle = value == null ? string.Empty : value; }
}
private string _grandTotalTitle = string.Empty;
public string GrandTotalTitle
{
get { return _grandTotalTitle; }
set { _grandTotalTitle = value == null ? string.Empty : value; }
}
private string _emptyDataText = "No Data To Display";
public string EmptyDataText
{
get { return _emptyDataText; }
set { _emptyDataText = value != null ? value.Length == 0 ? _emptyDataText : value : _emptyDataText; }
}
#endregion
#region Private Fields
private List<HtmlTable> _dataViewTables = null;
private double _numberOfDataViews = 1;
#endregion
#region Private Functions
public override void DataBind()
{
try
{
if (!_isSimpleData)
{
CreateHeaderRows();
CreateDataRows();
}
else
{
CreateSimpleDataTables();
}
if (_dataViewTables != null)
{
FillTablesInDataContainer();
}
else
{
divDataContainer.Controls.Clear();
divDataContainer.InnerHtml = _emptyDataText;
}
}
catch (Exception ex)
{
divDataContainer.Controls.Clear();
divDataContainer.InnerHtml = _emptyDataText;
}
}
private void CreateSimpleDataTables()
{
if (_simpleDataSource == null)
{
return;
}
List<double> columnTotals = new List<double>();
if (_isColumnTotals)
{
foreach (var item in _simpleDataSource)
{
columnTotals.Add(item.Value.Sum(delegate(string value) { double ctotal = 0; double.TryParse(value, out ctotal); return ctotal; }));
}
}
_dataViewTables = new List<HtmlTable>();
_numberOfDataViews = _simpleDataSource.Count < _maximumColumnsInRow ? 1 : Math.Ceiling(Convert.ToDouble(_simpleDataSource.Count) / _maximumColumnsInRow);
int position = 0;
for (int i = 1; i <= _numberOfDataViews; i++)
{
HtmlTable htable = new HtmlTable();
HtmlTableRow hrow = new HtmlTableRow();
htable.Rows.Add(hrow);
int currentlength = (i * _maximumColumnsInRow) < _simpleDataSource.Count ? (i * _maximumColumnsInRow) - position : _simpleDataSource.Count - ((i - 1) * _maximumColumnsInRow);
int maximumCellsInColumn = 0;
int index = -1;
maximumCellsInColumn = _simpleDataSource.ToList().FindAll(delegate(KeyValuePair<string, List<string>> item) { index++; return (index >= position && index < currentlength + position); }).Max(item => item.Value.Count);
for (int j = position; j < currentlength + position; j++)
{
HtmlTableCell headerCell = new HtmlTableCell();
headerCell.Attributes.Add("class", _headerCssClass);
headerCell.InnerHtml = _simpleDataSource.ElementAt(j).Key;
string cssClass = "";
for (int z = 0; z < maximumCellsInColumn; z++)
{
HtmlTableRow dataRow = new HtmlTableRow();
if (j == position)
{
htable.Rows.Add(new HtmlTableRow());
dataRow = htable.Rows[htable.Rows.Count - 1];
}
else
{
try
{
dataRow = htable.Rows[z + 1];
}
catch
{ }
}
if ((z % 2) == 0)
{
cssClass = _alternativeItemCssClass;
}
else
{
cssClass = _itemCssClass;
}
HtmlTableCell dataCell = new HtmlTableCell();
dataCell.Attributes.Add("class", cssClass);
dataCell.InnerHtml = _simpleDataSource.ElementAt(j).Value.Count > z ? _simpleDataSource.ElementAt(j).Value[z] : "";
dataRow.Cells.Add(dataCell);
}
hrow.Cells.Add(headerCell);
}
htable.Attributes.Add("class", _tableCssClass);
if (_isColumnTotals)
{
HtmlTableRow totalRow = new HtmlTableRow();
for (int j = position; j < currentlength + position; j++)
{
HtmlTableCell totalCell = new HtmlTableCell();
totalCell.Attributes.Add("class", _headerCssClass);
totalCell.InnerHtml = columnTotals[j].ToString();
totalRow.Cells.Add(totalCell);
htable.Rows.Add(totalRow);
}
}
_dataViewTables.Add(htable);
position += currentlength;
}
}
private void SetColumnTotals()
{
if (_isColumnTotals)
{
Dictionary<string, string> totalsRow = new Dictionary<string, string>();
foreach (var item in _columnHeaders)
{
double total = 0;
// total = _dataSource.Sum(currentItem => currentItem.Value.ContainsKey(item) ? double.Parse(currentItem.Value[item].ToString()) : 0.0);
total = _rowSetDataSource.Sum(delegate(KeyValuePair<string, Dictionary<string, string>> currentItem) { double currentValue = 0; double.TryParse(currentItem.Value[item].ToString(), out currentValue); return currentValue; });
totalsRow.Add(item, total.ToString());
}
_rowSetDataSource.Add("Totals", totalsRow);
}
}
private void CreateHeaderRows()
{
if (_columnHeaders == null)
{
return;
}
_dataViewTables = new List<HtmlTable>();
_numberOfDataViews = _columnHeaders.Count < _maximumColumnsInRow ? 1 : Math.Ceiling(Convert.ToDouble(_columnHeaders.Count) / _maximumColumnsInRow);
int position = 0;
for (int i = 1; i <= _numberOfDataViews; i++)
{
HtmlTable htable = new HtmlTable();
HtmlTableRow hrow = new HtmlTableRow();
HtmlTableCell dataCell = new HtmlTableCell();
dataCell.Attributes.Add("class", _headerCssClass);
dataCell.InnerHtml = _rowHeadersTitle;
hrow.Cells.Add(dataCell);
int currentlength = (i * _maximumColumnsInRow) < _columnHeaders.Count ? (i * _maximumColumnsInRow) - position : _columnHeaders.Count - ((i - 1) * _maximumColumnsInRow);
for (int j = position; j < currentlength + position; j++)
{
HtmlTableCell currentCell = new HtmlTableCell();
currentCell.Attributes.Add("class", _headerCssClass);
currentCell.InnerHtml = _columnHeaders[j];
hrow.Cells.Add(currentCell);
}
if (_isRowTotals)
{
HtmlTableCell currentCell = new HtmlTableCell();
currentCell.Attributes.Add("class", _headerCssClass);
currentCell.InnerHtml = "Total";
hrow.Cells.Add(currentCell);
}
htable.Rows.Add(hrow);
htable.Attributes.Add("class", _tableCssClass);
_dataViewTables.Add(htable);
position += currentlength;
}
}
private void CreateDataRows()
{
if (_rowHeaders == null || _rowSetDataSource == null)
{
for (int i = 0; i < _numberOfDataViews; i++)
{
HtmlTableRow emptyDataRow = new HtmlTableRow();
emptyDataRow.Cells.Add(new HtmlTableCell()
{
ColSpan = _dataViewTables[i].Rows[0].Cells.Count,
InnerHtml = _emptyDataText
}
);
emptyDataRow.Attributes.Add("class", _itemCssClass);
_dataViewTables[i].Rows.Add(emptyDataRow);
}
return;
}
if (_isColumnTotals)
{
SetColumnTotals();
}
int dataColumnPosition = 0;
List<double> allColumnTotalsInRow = new List<double>();
for (int i = 0; i < _numberOfDataViews; i++)
{
int dataRowPosition = 1;
HtmlTableRow columnTotalsRow = new HtmlTableRow();
if (_isColumnTotals)
{
columnTotalsRow.Cells.Add(new HtmlTableCell() { InnerHtml = "Total" });
columnTotalsRow.Cells[0].Attributes.Add("class", _headerCssClass);
}
int currentTableColumns = _dataViewTables[i].Rows[0].Cells.Count - 1;
currentTableColumns -= _isRowTotals ? 1 : 0;
foreach (var item in _rowHeaders)
{
HtmlTableRow rowHeader = new HtmlTableRow();
HtmlTableCell rowHeaderCell = new HtmlTableCell();
string cssClass = "";
if (dataRowPosition % 2 == 0)
{
cssClass = _itemCssClass;
}
else
{
cssClass = _alternativeItemCssClass;
}
rowHeaderCell.Attributes.Add("class", cssClass);
rowHeaderCell.InnerHtml = item;
rowHeader.Cells.Add(rowHeaderCell);
double rowTotal = 0;
for (int j = dataColumnPosition; j < dataColumnPosition + currentTableColumns; j++)
{
HtmlTableCell dataCell = new HtmlTableCell();
dataCell.Attributes.Add("class", cssClass);
dataCell.Attributes.CssStyle.Add("text-align", "center");
if (_startEndColumnColors != null)
{
if (j == 0 || j == _columnHeaders.Count - 1)
{
dataCell.Attributes.CssStyle.Add("background-color", _startEndColumnColors[dataRowPosition - 1]);
dataCell.Attributes.CssStyle.Add("color", "#ffffff");
}
}
if (_rowSetDataSource[item].ContainsKey(_columnHeaders[j]))
{
dataCell.InnerHtml = _rowSetDataSource[item][_columnHeaders[j]];
double currentValue = 0;
double.TryParse(_rowSetDataSource[item][_columnHeaders[j]], out currentValue);
rowTotal += currentValue;
if (_isColumnTotals && dataRowPosition == 1)
{
HtmlTableCell totalCell = new HtmlTableCell();
totalCell.Attributes.Add("class", _headerCssClass);
totalCell.InnerHtml = _rowSetDataSource["Totals"][_columnHeaders[j]];
columnTotalsRow.Cells.Add(totalCell);
}
}
else
{
dataCell.InnerHtml = " ";
}
rowHeader.Cells.Add(dataCell);
}
if (_isGrandTotal)
{
if (i == 0)
{
allColumnTotalsInRow.Add(rowTotal);
}
else
{
allColumnTotalsInRow[dataRowPosition - 1] += rowTotal;
}
}
dataRowPosition++;
if (_isRowTotals)
{
HtmlTableCell totalCell = new HtmlTableCell();
totalCell.Attributes.Add("class", cssClass);
totalCell.Attributes.CssStyle.Add("text-align", "center");
totalCell.InnerHtml = string.Format("<b>{0}</b>", rowTotal.ToString());
rowHeader.Cells.Add(totalCell);
}
_dataViewTables[i].Rows.Add(rowHeader);
}
if (_isRowTotals)
{
HtmlTableCell totalCell = new HtmlTableCell();
totalCell.Attributes.Add("class", _headerCssClass);
totalCell.InnerHtml = "";
columnTotalsRow.Cells.Add(totalCell);
}
_dataViewTables[i].Rows.Add(columnTotalsRow);
dataColumnPosition += currentTableColumns;
#region Grand Total
if (i == _numberOfDataViews - 1)
{
if (_isGrandTotal)
{
HtmlTableCell grandTotalCell = new HtmlTableCell();
grandTotalCell.Attributes.Add("class", _headerCssClass);
grandTotalCell.InnerHtml = _grandTotalTitle.Trim().Length == 0 ? "Grand Total" : _grandTotalTitle;
_dataViewTables[i].Rows[0].Cells.Add(grandTotalCell);
for (int x = 1; x <= _rowHeaders.Count; x++)
{
grandTotalCell = new HtmlTableCell();
grandTotalCell.Attributes.Add("class", _headerCssClass);
grandTotalCell.InnerHtml = allColumnTotalsInRow[x - 1].ToString();
_dataViewTables[i].Rows[x].Cells.Add(grandTotalCell);
}
grandTotalCell = new HtmlTableCell();
grandTotalCell.Attributes.Add("class", _headerCssClass);
grandTotalCell.InnerHtml = "";
_sumOfGrandTotals = allColumnTotalsInRow.Sum();
if (IsSumOfGrandTotalsShow)
{
grandTotalCell.InnerHtml = _sumOfGrandTotals.ToString();
}
_dataViewTables[i].Rows[_dataViewTables[i].Rows.Count - 1].Cells.Add(grandTotalCell);
}
}
#endregion
}
}
private void FillTablesInDataContainer()
{
int i = 0;
divDataContainer.Controls.Clear();
foreach (var item in _dataViewTables)
{
divDataContainer.Controls.Add(item);
i++;
if (_dataViewTables.Count > 1 && i != _dataViewTables.Count)
{
divDataContainer.Controls.Add(GetDataDivider());
}
}
// Session["_dataViewTables"] = _dataViewTables;
}
private HtmlGenericControl GetDataDivider()
{
HtmlGenericControl hgControl = new HtmlGenericControl();
switch (_dataDivider)
{
case DataSeparator.SingleBreak:
hgControl.InnerHtml = "<br />";
break;
case DataSeparator.DoubleBreack:
hgControl.InnerHtml = "<br /> <br />";
break;
case DataSeparator.SingleHorizontalLine:
hgControl.InnerHtml = "<hr style=\"display :block; width:100%;\" />";
break;
case DataSeparator.DoubleHorizontalLine:
hgControl.InnerHtml = "<hr style=\"display :block;width:100%;float:left;\"/><hr style=\"display :block;width:100%;float:left;\"/>";
break;
}
return hgControl;
}
#endregion
}