void
RadPivotGrid1_CellDataBound(
object
sender, PivotGridCellDataBoundEventArgs e)
{
PivotGridDataCell cell = e.Cell
as
PivotGridDataCell;
if
(cell !=
null
)
{
// We do not need to attach onclick event on cell which does not have values
if
(cell.DataItem !=
null
)
{
string
argument = GetCommandArguments(cell);
string
script =
string
.Format(
"OpenDetailsWindow('{0}')"
, argument);
cell.Attributes.Add(
"onclick"
, script);
}
index++;
}
}
<script type=
"text/javascript"
>
function
OpenDetailsWindow(argument)
{
$find(
"<%= RadAjaxPanel1.ClientID %>"
).ajaxRequest(argument);
}
</script>
private
void
AdjustRowAndColumnIndexes(PivotGridDataCell cell,
ref
int
rowIndexesCount,
ref
int
columnIndexesCount)
{
//if aggregates are more than one additional cells are rendered, so we need to exclude their values from the query
if
(aggregateFields.Count > 1)
{
if
(RadPivotGrid1.AggregatesPosition == PivotGridAxis.Columns)
{
if
(cell.CellType == PivotGridDataCellType.DataCell ||
cell.CellType == PivotGridDataCellType.RowTotalDataCell ||
cell.CellType == PivotGridDataCellType.RowAndColumnTotal ||
cell.CellType == PivotGridDataCellType.RowGrandTotalDataCell ||
cell.CellType == PivotGridDataCellType.ColumnGrandTotalRowTotal)
{
columnIndexesCount--;
}
}
else
{
if
(cell.CellType != PivotGridDataCellType.RowTotalDataCell &&
cell.CellType != PivotGridDataCellType.ColumnGrandTotalRowTotal)
{
rowIndexesCount--;
}
}
}
// if row total or grand total cell is hit we need to escape its values from query
if
(cell.CellType == PivotGridDataCellType.RowTotalDataCell ||
cell.CellType == PivotGridDataCellType.ColumnGrandTotalRowTotal ||
cell.CellType == PivotGridDataCellType.RowGrandTotalDataCell)
{
rowIndexesCount--;
}
// if column total or grand total cell is hit we need to escape its values from query
if
(cell.CellType == PivotGridDataCellType.ColumnTotalDataCell ||
cell.CellType == PivotGridDataCellType.ColumnGrandTotalDataCell ||
cell.CellType == PivotGridDataCellType.RowGrandTotalColumnTotal ||
cell.CellType == PivotGridDataCellType.RowAndColumnTotal ||
cell.CellType == PivotGridDataCellType.ColumnGrandTotalRowTotal)
{
columnIndexesCount--;
}
}
int
index = 0;
int
[] allFakeColumnCells =
null
;
bool
isFirstDataCell =
true
;
int
countOfFakeRowCells = 0;
int
cellsCount = 0;
string
firstRowID =
string
.Empty;
string
currentRowID =
string
.Empty;
int
key = 0;
void
RadPivotGrid1_CellDataBound(
object
sender, PivotGridCellDataBoundEventArgs e)
{
PivotGridDataCell cell = e.Cell
as
PivotGridDataCell;
if
(cell !=
null
)
{
// If this is the first data cell we need to populate the collection whith fake columns cells count
if
(isFirstDataCell)
{
PopulateFakeColumnsCellCollection(cell);
isFirstDataCell =
false
;
}
// We do not need to attach onclick event on cell which does not have values
if
(cell.DataItem !=
null
)
{
string
argument = GetCommandArguments(cell);
string
script =
string
.Format(
"OpenDetailsWindow('{0}')"
, argument);
cell.Attributes.Add(
"onclick"
, script);
}
index++;
}
}
// This methos is executed only for the first cell from the first row
private
void
PopulateFakeColumnsCellCollection(PivotGridDataCell cell)
{
PivotGridDataItem item = cell.NamingContainer
as
PivotGridDataItem;
cellsCount = item.Cells.Count;
allFakeColumnCells =
new
int
[cellsCount];
firstRowID = item.UniqueID;
for
(
int
i = 0; i < cellsCount; i++)
{
int
countOfFakeCells = GetCountOfFakeColumnCells(item.Cells[i]
as
PivotGridDataCell);
allFakeColumnCells[i] = countOfFakeCells;
}
}
private
int
GetCountOfFakeRowCells(PivotGridDataCell cell)
{
int
count = 0;
//if aggregates are more than one additional cells are rendered, so we need to exclude their values from the query
if
(aggregateFields.Count > 1)
{
if
(RadPivotGrid1.AggregatesPosition == PivotGridAxis.Rows)
{
if
(cell.CellType != PivotGridDataCellType.RowTotalDataCell &&
cell.CellType != PivotGridDataCellType.ColumnGrandTotalRowTotal)
{
count++;
}
}
}
// if row total or grand total cell is hit we need to escape its values from query
if
(cell.CellType == PivotGridDataCellType.RowTotalDataCell ||
cell.CellType == PivotGridDataCellType.ColumnGrandTotalRowTotal ||
cell.CellType == PivotGridDataCellType.RowGrandTotalDataCell)
{
count++;
}
return
count;
}
public
string
GetCommandArguments(PivotGridDataCell cell)
{
// True when first cell of each row is hit
if
(currentRowID != cell.NamingContainer.UniqueID)
{
index = 0;
currentRowID = cell.NamingContainer.UniqueID;
countOfFakeRowCells = GetCountOfFakeRowCells(cell);
}
object
[] rowIndexes = cell.ParentRowIndexes;
object
[] columnIndexes = cell.ParentColumnIndexes;
int
rowIndexesCount = rowIndexes.Count();
int
columnIndexesCount = columnIndexes.Count();
int
countOfFakeColumnCells = allFakeColumnCells[index];
rowIndexesCount -= countOfFakeRowCells;
columnIndexesCount -= countOfFakeColumnCells;
StringBuilder buider = BuildArguments(rowIndexes, columnIndexes, rowIndexesCount, columnIndexesCount);
return
buider.ToString();
}
private
int
GetCountOfFakeColumnCells(PivotGridDataCell cell)
{
int
count = 0;
if
(aggregateFields.Count > 1)
{
if
(RadPivotGrid1.AggregatesPosition == PivotGridAxis.Columns)
{
if
(cell.CellType == PivotGridDataCellType.DataCell ||
cell.CellType == PivotGridDataCellType.RowTotalDataCell ||
cell.CellType == PivotGridDataCellType.RowAndColumnTotal ||
cell.CellType == PivotGridDataCellType.RowGrandTotalDataCell ||
cell.CellType == PivotGridDataCellType.ColumnGrandTotalRowTotal)
{
count++;
}
}
}
// if column total or grand total cell is hit we need to escape its values from query
if
(cell.CellType == PivotGridDataCellType.ColumnTotalDataCell ||
cell.CellType == PivotGridDataCellType.RowAndColumnTotal ||
cell.CellType == PivotGridDataCellType.ColumnGrandTotalRowTotal ||
cell.CellType == PivotGridDataCellType.ColumnGrandTotalDataCell ||
cell.CellType == PivotGridDataCellType.RowGrandTotalColumnTotal)
{
count++;
}
return
count;
}
public
Dictionary<
int
,
string
> Arguments
{
get
{
if
(Session[
"Arguments"
] ==
null
)
{
Session[
"Arguments"
] =
new
Dictionary<
int
,
string
>();
}
return
Session[
"Arguments"
]
as
Dictionary<
int
,
string
>;
}
set
{
Session[
"Arguments"
] = value;
}
}
public
string
GetCommandArguments(PivotGridDataCell cell)
{
…
StringBuilder buider = BuildArguments(rowIndexes, columnIndexes, rowIndexesCount, columnIndexesCount);
return
buider.ToString();
}
private
StringBuilder BuildArguments(
object
[] rowIndexes,
object
[] columnIndexes,
int
rowIndexesCount,
int
columnIndexesCount)
{
StringBuilder buider =
new
StringBuilder();
ReplaceArgumentsWithNumbers(rowIndexes, rowFields, rowIndexesCount, buider);
ReplaceArgumentsWithNumbers(columnIndexes, columnFields, columnIndexesCount, buider);
// Remove the semicolon in the end
if
(buider.Length > 1)
{
buider.Remove(buider.Length - 1, 1);
}
return
buider;
}
private
void
ReplaceArgumentsWithNumbers(
object
[] cellIndexes, List<PivotGridField> fields,
int
indexesCount, StringBuilder buider)
{
for
(
int
i = 0; i < indexesCount; i++)
{
string
firstPart = fields[i].DataField;
string
secondPart = cellIndexes[i].ToString();
if
(Arguments.ContainsValue(firstPart))
{
buider.Append(Arguments.FirstOrDefault(a => a.Value == firstPart).Key);
AppendSecondParts(buider, secondPart);
}
else
{
Arguments.Add(key, firstPart);
buider.Append(
string
.Format(
"{0}"
, key.ToString()));
key++;
AppendSecondParts(buider, secondPart);
}
}
}
private
void
AppendSecondParts(StringBuilder buider,
string
secondPart)
{
if
(Arguments.ContainsValue(secondPart))
{
buider.Append(
string
.Format(
"~{0};"
, Arguments.FirstOrDefault(a => a.Value == secondPart).Key));
}
else
{
Arguments.Add(key, secondPart);
buider.Append(
string
.Format(
"~{0};"
, key.ToString()));
key++;
}
}
void
RadAjaxPanel1_AjaxRequest(
object
sender, AjaxRequestEventArgs e)
{
StringBuilder whereClause =
new
StringBuilder();
if
(!
string
.IsNullOrEmpty(e.Argument.ToString()))
{
string
[] elements = e.Argument.ToString().Split(
new
char
[] {
';'
}, StringSplitOptions.RemoveEmptyEntries);
foreach
(var element
in
elements)
{
var group = element.Split(
new
char
[] {
'~'
}, StringSplitOptions.RemoveEmptyEntries);
int
firstPart = Convert.ToInt32(group[0]);
int
secondPart = Convert.ToInt32(group[1]);
whereClause.Append(
string
.Format(
"{0} = '{1}' AND "
, Arguments[firstPart], Arguments[secondPart]));
}
…
}
Radoslav Kirilov is a software developer at one of Telerik’s ASP.NET AJAX teams. Ever since he joined the company in 2009, he has been working on the data-bound and date-picker controls. His interests are primarily concentrated on ASP.NET, AJAX, MVC, SQL and best practices.