Work around: create a custom GridCheckBoxHeaderCellElement and override the SetCheckBoxState method
public class MyGridCheckBoxHeaderCellElement : GridCheckBoxHeaderCellElement
{
public MyGridCheckBoxHeaderCellElement(GridViewColumn column, GridRowElement row)
: base(column, row)
{
}
protected override Type ThemeEffectiveType
{
get { return typeof(GridHeaderCellElement); }
}
protected override bool SetCheckBoxState()
{
bool foundNonCheckedRows = false;
foreach (GridViewRowInfo row in this.ViewInfo.Rows)
{
foundNonCheckedRows = this.CheckCheckBoxValueForAllRows(row, foundNonCheckedRows);
if (foundNonCheckedRows)
{
SetCheckBoxState(ToggleState.Off);
break;
}
}
if (!foundNonCheckedRows && this.ViewInfo.Rows.Count > 0) //we must have at least one row in order to check the header cell
{
SetCheckBoxState(ToggleState.On);
}
return foundNonCheckedRows;
}
private bool CheckCheckBoxValueForAllRows(GridViewRowInfo row, bool foundNonCheckedRows)
{
GridViewChildRowCollection currentRowColection;
if (foundNonCheckedRows)
{
return foundNonCheckedRows;
}
if (row.HasChildRows())
{
currentRowColection = row.ChildRows;
}
else
{
currentRowColection = row.ViewInfo.Rows;
}
foreach (GridViewRowInfo rowInfo in currentRowColection)
{
GridViewGroupRowInfo groupInfo = rowInfo as GridViewGroupRowInfo;
if (groupInfo != null)
{
foundNonCheckedRows = this.CheckCheckBoxValueForAllRows(groupInfo, foundNonCheckedRows);
}
else
{
object cellValue = rowInfo.Cells[this.ColumnIndex].Value;
bool? valueFromColumnTypeConvertor = null;
if (this.ColumnInfo is GridViewDataColumn)
{
TypeConverter convertor = ((GridViewDataColumn)this.ColumnInfo).DataTypeConverter;
if (convertor != null && (convertor.CanConvertTo(typeof(bool)) || convertor.CanConvertTo(typeof(ToggleState))))
{
try
{
valueFromColumnTypeConvertor = Convert.ToBoolean(convertor.ConvertTo(cellValue, typeof(bool)));
}
catch (FormatException)//convert to bool fails
{
}
catch (NotSupportedException)//coverting NULL
{
}
}
}
try
{
if (rowInfo != this.RowInfo &&
(cellValue == null || cellValue == DBNull.Value) ||
(valueFromColumnTypeConvertor.HasValue && !valueFromColumnTypeConvertor.Value) ||
(!valueFromColumnTypeConvertor.HasValue && !Convert.ToBoolean(cellValue)))
{
foundNonCheckedRows = true;
}
}
catch (FormatException)//convert to bool fails
{
}
}
}
return foundNonCheckedRows;
}
}