To reproduce:
public Form1()
{
InitializeComponent();
BindingList<Item> items = new BindingList<Item>();
for (int i = 0; i < 30; i++)
{
if (i % 3 == 0)
{
items.Add(new Item(i,"Item" + i, IndeterminateBoolean.YesAndNo));
}
else if (i % 3 == 1)
{
items.Add(new Item(i, "Item" + i, IndeterminateBoolean.Yes));
}
else
{
items.Add(new Item(i, "Item" + i, IndeterminateBoolean.No));
}
}
this.radGridView1.DataSource = items;
GridViewCheckBoxColumn checkBox = new GridViewCheckBoxColumn("CheckBoxCol");
checkBox.DataTypeConverter = new IndeterminateBooleanToggleStateConverter();
checkBox.FieldName = "IsActive";
checkBox.ThreeState = true;
this.radGridView1.Columns.Add(checkBox);
this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
this.radGridView1.EnableFiltering = true;
this.radGridView1.ShowHeaderCellButtons = true;
this.radGridView1.ShowFilteringRow = false;
}
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
public IndeterminateBoolean IsActive { get; set; }
public Item(int id, string name, IndeterminateBoolean isActive)
{
this.Id = id;
this.Name = name;
this.IsActive = isActive;
}
}
public enum IndeterminateBoolean
{
No,
Yes,
YesAndNo
}
public class IndeterminateBooleanToggleStateConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(ToggleState);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof(ToggleState);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value is ToggleState)
{
switch ((ToggleState)value)
{
case ToggleState.On:
return IndeterminateBoolean.Yes;
case ToggleState.Off:
return IndeterminateBoolean.No;
case ToggleState.Indeterminate:
default:
return IndeterminateBoolean.YesAndNo;
}
}
else
{
return base.ConvertFrom(context, culture, value);
}
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(ToggleState))
{
if (value is IndeterminateBoolean)
{
switch ((IndeterminateBoolean)value)
{
case IndeterminateBoolean.Yes:
return ToggleState.On;
case IndeterminateBoolean.No:
return ToggleState.Off;
case IndeterminateBoolean.YesAndNo:
default:
return ToggleState.Indeterminate;
}
}
if (value is string)
{
switch (((string)value ?? string.Empty).Trim())
{
case "Yes":
return ToggleState.On;
case "No":
case "":
return ToggleState.Off;
case "Both":
default:
return ToggleState.Indeterminate;
}
}
else
{
return base.ConvertTo(context, culture, value, destinationType);
}
}
else
{
return base.ConvertTo(context, culture, value, destinationType);
}
}
}
Workaround: use the custom filtering functionality: http://docs.telerik.com/devtools/winforms/gridview/filtering/custom-filtering
You can access the RadGridView.FilterDescriptors collection and according to the FilterDescriptor.Expression property to determine whether the row will be visible or not.
To reproduce:
- Create load on demand hierarchy.
- Open the excel filter popup.
- The RowSourceNeeded event fires for all rows.
Workaround:
public class MyGridHeaderCellElement : GridHeaderCellElement
{
public MyGridHeaderCellElement(GridViewDataColumn col, GridRowElement row) : base(col, row)
{
}
protected override Type ThemeEffectiveType
{
get { return typeof(GridHeaderCellElement); }
}
protected override IGridFilterPopup CreateFilterPopup()
{
this.GridControl.Tag = "FileterInitializing";
return base.CreateFilterPopup();
}
}
// in the main forms you cab skip the event code execution while the popup is initialized
private void RadGridView1_FilterPopupInitialized(object sender, FilterPopupInitializedEventArgs e)
{
this.radGridView1.Tag = null;
}
private void RadGridView1_CreateCell(object sender, GridViewCreateCellEventArgs e)
{
if (object.ReferenceEquals(e.CellType, typeof(GridHeaderCellElement)))
{
e.CellType = typeof(MyGridHeaderCellElement);
}
}
void radGridView1_RowSourceNeeded(object sender, GridViewRowSourceNeededEventArgs e)
{
if (radGridView1.Tag != null && radGridView1.Tag == "FileterInitializing")
{
return;
}
//other code
}
The behavior should be consistent no matter if you change the current column or the current row.
To reproduce:
Add the following view:
for (int i = 0; i < 8; i++)
{
radGridView2.Columns.Add("Col" + (i+1));
}
ColumnGroupsViewDefinition view = new ColumnGroupsViewDefinition();
view.ColumnGroups.Add(new GridViewColumnGroup("G1"));
view.ColumnGroups.Add(new GridViewColumnGroup("G2"));
view.ColumnGroups.Add(new GridViewColumnGroup("G3"));
view.ColumnGroups[0].Rows.Add(new GridViewColumnGroupRow());
view.ColumnGroups[0].Rows[0].ColumnNames.Add("Col1");
view.ColumnGroups[0].Rows[0].ColumnNames.Add("Col2");
view.ColumnGroups[0].Rows[0].ColumnNames.Add("Col3");
view.ColumnGroups[1].Rows.Add(new GridViewColumnGroupRow());
view.ColumnGroups[1].Rows[0].ColumnNames.Add("Col4");
view.ColumnGroups[1].Rows[0].ColumnNames.Add("Col5");
view.ColumnGroups[2].Rows.Add(new GridViewColumnGroupRow());
view.ColumnGroups[2].Rows[0].ColumnNames.Add("Col6");
view.ColumnGroups[2].Rows[0].ColumnNames.Add("Col7");
view.ColumnGroups[2].Rows[0].ColumnNames.Add("Col8");
radGridView2.ViewDefinition = view;
for (int i = 0; i < 10; i++)
{
radGridView2.Rows.Add("row"+i, "test","test","test","test","test","test");
}
radGridView2.Columns[2].IsVisible = false;
radGridView2.Columns[7].IsVisible = false;
- Then export the grid with the spread exporter.
To reproduce: use the following code snippet. You will notice that the "Accounting Manager" group is missing.
private void Form1_Load(object sender, EventArgs e)
{
this.customersTableAdapter.Fill(this.nwindDataSet.Customers);
this.radGridView1.DataSource = this.customersBindingSource;
ColumnGroupsViewDefinition view = new ColumnGroupsViewDefinition();
view.ColumnGroups.Add(new GridViewColumnGroup("Customer Contact"));
view.ColumnGroups.Add(new GridViewColumnGroup("Details"));
view.ColumnGroups[1].Groups.Add(new GridViewColumnGroup("Address"));
view.ColumnGroups[1].Groups.Add(new GridViewColumnGroup("Contact"));
view.ColumnGroups[0].Rows.Add(new GridViewColumnGroupRow());
view.ColumnGroups[0].Rows[0].ColumnNames.Add("CompanyName");
view.ColumnGroups[0].Rows[0].ColumnNames.Add("ContactName");
view.ColumnGroups[0].Rows[0].ColumnNames.Add("ContactTitle");
view.ColumnGroups[1].Groups[0].Rows.Add(new GridViewColumnGroupRow());
view.ColumnGroups[1].Groups[0].Rows[0].ColumnNames.Add("Address");
view.ColumnGroups[1].Groups[0].Rows[0].ColumnNames.Add("City");
view.ColumnGroups[1].Groups[0].Rows[0].ColumnNames.Add("Country");
view.ColumnGroups[1].Groups[1].Rows.Add(new GridViewColumnGroupRow());
view.ColumnGroups[1].Groups[1].Rows[0].ColumnNames.Add("Phone");
view.ColumnGroups[1].Groups[1].Rows[0].ColumnNames.Add("Fax");
radGridView1.ViewDefinition = view;
GroupDescriptor descriptor = new GroupDescriptor();
descriptor.GroupNames.Add("ContactTitle", ListSortDirection.Ascending);
this.radGridView1.GroupDescriptors.Add(descriptor);
this.radGridView1.Groups[0].GroupRow.IsPinned = true;
}
Enable the ability to MERGE seperate rows (different records), like found in ITunes "Songs" mode where is shows the artwork (then artist,release undernearth) in a custom class, then the related song rows to the right. Your competitor Dev Express has it already in place. See youtube video here : https://www.youtube.com/watch?v=TfPXwE7GcXs Cheers
To reproduce:
public Form1()
{
InitializeComponent();
radGridView1.Columns.Add(new GridViewTextBoxColumn("Text1"));
radGridView1.Columns.Add(new GridViewTextBoxColumn("Text2"));
radGridView1.Columns.Add(new GridViewTextBoxColumn("Text3"));
radGridView1.Columns.Add(new GridViewTextBoxColumn("Text4"));
radGridView1.Columns.Add(new GridViewTextBoxColumn("Text5"));
radGridView1.Columns.Add(new GridViewTextBoxColumn("Text6"));
radGridView1.Columns.Add(new GridViewTextBoxColumn("Text7"));
radGridView1.Columns.Add(new GridViewTextBoxColumn("Text8"));
radGridView1.Columns.Add(new GridViewDateTimeColumn("Date1"));
radGridView1.Columns.Add(new GridViewDecimalColumn("Amount1"));
radGridView1.Columns.Add(new GridViewDecimalColumn("Amount2"));
radGridView1.Columns.Add(new GridViewDecimalColumn("Amount3"));
radGridView1.Columns.Add(new GridViewDecimalColumn("Amount4"));
radGridView1.Columns.Add(new GridViewDecimalColumn("Amount5"));
radGridView1.Columns.Add(new GridViewDecimalColumn("Amount6"));
radGridView1.DataSource = GetDataSet();
}
private DataTable GetDataSet()
{
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("Text1", typeof(string)));
dt.Columns.Add(new DataColumn("Text2", typeof(string)));
dt.Columns.Add(new DataColumn("Text3", typeof(string)));
dt.Columns.Add(new DataColumn("Text4", typeof(string)));
dt.Columns.Add(new DataColumn("Text5", typeof(string)));
dt.Columns.Add(new DataColumn("Text6", typeof(string)));
dt.Columns.Add(new DataColumn("Text7", typeof(string)));
dt.Columns.Add(new DataColumn("Text8", typeof(string)));
dt.Columns.Add(new DataColumn("Date1", typeof(DateTime)));
dt.Columns.Add(new DataColumn("Amount1", typeof(decimal)));
dt.Columns.Add(new DataColumn("Amount2", typeof(decimal)));
dt.Columns.Add(new DataColumn("Amount3", typeof(decimal)));
dt.Columns.Add(new DataColumn("Amount4", typeof(decimal)));
dt.Columns.Add(new DataColumn("Amount5", typeof(decimal)));
dt.Columns.Add(new DataColumn("Amount6", typeof(decimal)));
for (int i = 1; i <= 150000; i++)
{
dt.Rows.Add(new object[]
{
"Example Text For Row " + i.ToString(),
"Example Text For Row " + i.ToString(),
"More Example Text For Row " + i.ToString(),
"Even More Example Text For Row " + i.ToString(),
"Lots More Example Text For Row " + i.ToString(),
"Excessive Example Text For Row " + i.ToString(),
"Extra Example Text For Row " + i.ToString(),
"Random Example Text For Row " + i.ToString(),
new DateTime(2015, i % 12 + 1, i % 28 + 1),
i % 2 * 10000, i % 3 * 10000, i % 5 * 10000, i % 7 * 10000, i % 11 * 10000, i % 13 * 10000
});
}
return dt;
}
string fileName = @"..\..\" + DateTime.Now.ToLongTimeString().Replace(":", "_");
private void button1_Click(object sender, EventArgs e)
{
SaveFileDialog sfdExportToExcel = new SaveFileDialog();
DialogResult exportBrowse = sfdExportToExcel.ShowDialog();
if (exportBrowse == DialogResult.OK)
{
GridViewSpreadExport exporter = new GridViewSpreadExport(this.radGridView1);
exporter.SheetMaxRows = Telerik.WinControls.UI.Export.ExcelMaxRows._1048576;
exporter.FileExportMode = FileExportMode.CreateOrOverrideFile;
exporter.ExportVisualSettings = false;
exporter.AsyncExportCompleted += exporter_AsyncExportCompleted;
SpreadExportRenderer renderer = new SpreadExportRenderer();
exporter.RunExportAsync(fileName, renderer);
}
}
The selection mode should be as in Windows Explorer - when Control is pressed, one should be able to move the current row with the up/down arrow keys and when Space is pressed, the current row should be selected/deselected.
This implementation can be used for the time being:
public partial class Form1 : RadForm
{
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
AddGridSimpleUnbound();
radGridView1.MultiSelect = true;
BaseGridBehavior gridBehavior = radGridView1.GridBehavior as BaseGridBehavior;
gridBehavior.UnregisterBehavior(typeof(GridViewDataRowInfo));
gridBehavior.RegisterBehavior(typeof(GridViewDataRowInfo), new MyRowBehavior());
radGridView1.GridViewElement.Navigator = new MyNavigator();
}
class MyNavigator : BaseGridNavigator
{
protected override bool DoMultiSelect(GridViewRowInfo oldRow, GridViewColumn oldColumn, GridViewRowInfo row, GridViewColumn column)
{
if (!this.IsShiftButtonPressed && this.IsControlButtonPressed && !this.IsMouseSelection)
{
return true;
}
return base.DoMultiSelect(oldRow, oldColumn, row, column);
}
}
class MyRowBehavior : GridDataRowBehavior
{
bool kbdSelection = false;
public override bool ProcessKeyPress(KeyPressEventArgs keys)
{
if (kbdSelection)
{
kbdSelection = false;
return true;
}
return base.ProcessKeyPress(keys);
}
public override bool ProcessKey(KeyEventArgs keys)
{
if (keys.KeyCode == Keys.Space && this.GridControl.MultiSelect && keys.Control)
{
this.GridControl.CurrentRow.IsSelected ^= true;
kbdSelection = true;
return false;
}
else
{
return base.ProcessKey(keys);
}
}
}
}
To reproduce:
public Form1()
{
InitializeComponent();
for (int i = 0; i < 10; i++)
{
this.radGridView1.Columns.Add("Col"+i);
}
this.radGridView1.TableElement.RowDragHint = null;
}
Workaround:
public Form1()
{
InitializeComponent();
for (int i = 0; i < 10; i++)
{
this.radGridView1.Columns.Add("Col"+i);
}
this.radGridView1.TableElement.RowDragHint = null;
CustomRadGridViewDragDropService service = new CustomRadGridViewDragDropService(this.radGridView1.GridViewElement);
this.radGridView1.GridViewElement.RegisterService(service);
}
public class CustomRadGridViewDragDropService : RadGridViewDragDropService
{
public CustomRadGridViewDragDropService(RadGridViewElement gridViewElement) : base(gridViewElement)
{
}
public override string Name
{
get
{
return typeof(RadGridViewDragDropService).Name;
}
}
protected override void PrepareDragHint(ISupportDrop dropTarget)
{
if (this.GridViewElement.TableElement.RowDragHint == null)
{
return;
}
base.PrepareDragHint(dropTarget);
}
protected override IGridDragDropBehavior GetDragDropBehavior()
{
IGridDragDropBehavior behavior = null;
ISupportDrop dropTarget = this.DropTarget;
if (dropTarget is GridHeaderCellElement)
{
behavior = new CustomGridColumnDragDropBehvavior();
return behavior;
}
return base.GetDragDropBehavior();
}
}
public class CustomGridColumnDragDropBehvavior : GridColumnDragDropBehvavior
{
public override Size GetDragHintSize(ISupportDrop dropTarget)
{
if (this.DragHint==null)
{
return new Size(0, 0);
}
return base.GetDragHintSize(dropTarget);
}
}
To reproduce:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.RadGridView1.DataSource = Me.ProductsBindingSource
Me.ProductsTableAdapter.Fill(Me.NwindDataSet.Products)
Dim obj As New ConditionalFormattingObject("MyCondition", ConditionTypes.Greater, "30", "", False)
obj.CellBackColor = Color.SkyBlue
obj.CellForeColor = Color.Red
obj.TextAlignment = ContentAlignment.MiddleRight
Me.RadGridView1.Columns("UnitPrice").ConditionalFormattingObjectList.Add(obj)
End Sub
Private Sub RadButton1_Click(sender As Object, e As EventArgs) Handles RadButton1.Click
Dim mySQL As String = "SELECT * FROM Products where ProductName = 'Chaii'"
Dim myTable As DataTable = getDataInTable(mySQL, My.Settings.NwindConnectionString)
Me.RadGridView1.DataSource = myTable
End Sub
Public Shared Function getDataInTable(mySQLorTable As String, myConnectionString As String, Optional myTimeout As Integer = 30) As DataTable
Using myConnection As New System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\Nwind.mdb")
Dim myCommand As New OleDb.OleDbCommand(mySQLorTable, myConnection)
myConnection.Open()
Dim myDataTable As New DataTable
Dim myAdapter As New OleDb.OleDbDataAdapter(myCommand)
myAdapter.Fill(myDataTable)
Return myDataTable
End Using
End Function
When you click the button, the grid is refilled with the query result which does not contain any rows. As a result, a DataException is thrown for each column: "There is no property descriptor corresponding to property name: 'ColumnName'" .
Workaround: clear the conditional formatting objects, reset the DataSource and add the conditional formatting objects back
To reproduce:
public Form1()
{
InitializeComponent();
BindingList<Item> items = new BindingList<Item>();
for (int i = 0; i < 10; i++)
{
items.Add(new Item(i,"Item" + i , DeliveryType.Type1));
}
for (int i = 10; i < 20; i++)
{
items.Add(new Item(i, "Item" + i, DeliveryType.Type2));
}
for (int i = 20; i < 30; i++)
{
items.Add(new Item(i, "Item" + i, DeliveryType.Type3));
}
this.radGridView1.DataSource = items;
this.radGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill;
this.radGridView1.EnableFiltering = true;
CompositeFilterDescriptor compositeFilter = new CompositeFilterDescriptor();
compositeFilter.FilterDescriptors.Add(new FilterDescriptor("DeliveryType", FilterOperator.IsEqualTo, DeliveryType.Type2));
compositeFilter.FilterDescriptors.Add(new FilterDescriptor("DeliveryType", FilterOperator.IsEqualTo, DeliveryType.Type3));
compositeFilter.LogicalOperator = FilterLogicalOperator.Or;
this.radGridView1.FilterDescriptors.Add(compositeFilter);
}
public class Item
{
public int Id { get; set; }
public string Name { get; set; }
public DeliveryType DeliveryType { get; set; }
public Item(int id, string name, DeliveryType deliveryType)
{
this.Id = id;
this.Name = name;
this.DeliveryType = deliveryType;
}
}
public enum DeliveryType
{
Type1,
Type2,
Type3
}
Workaround: use custom filtering: http://docs.telerik.com/devtools/winforms/gridview/filtering/custom-filtering
To reproduce:
GridViewImageColumn imageColumn = new GridViewImageColumn();
imageColumn.Name = "ImageColumn";
imageColumn.FieldName = "ImageColumn";
imageColumn.HeaderText = "Picture";
radGridView1.MasterTemplate.Columns.Add(imageColumn);
List<classBinding> databinding = new List<classBinding>();
for (int i = 0; i < 35000; i++)
{
databinding.Add(new classBinding()
{
ImageColumn = Properties.Resources.Alarm2,
});
}
radGridView1.DataSource = databinding;
public class classBinding
{
public System.Drawing.Bitmap ImageColumn { get; set; }
}
Workaround: suspend columns notifications when preview dropping and resume the notification after the drag drop service has stopped:
Dim svc As RadDragDropService = Me.RadGridView1.GridViewElement.GetService(Of RadDragDropService)()
AddHandler svc.Stopped, svc_Stopped
AddHandler svc.PreviewDragDrop, AddressOf svc_PreviewDragDrop
Private Sub svc_PreviewDragDrop(sender As Object, e As RadDropEventArgs)
For Each col As GridViewColumn In Me.RadGridView1.Columns
col.SuspendPropertyNotifications()
Next
End Sub
Private Function svc_Stopped() As Object
For Each col As GridViewColumn In Me.RadGridView1.Columns
col.ResumePropertyNotifications()
Next
End Function
To reproduce:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
var data = new List<Thing>();
this.radGridView1.DataSource = data ;
this.radGridView1.DataError += RadGridView1_DataError;
}
private void RadGridView1_DataError(object sender, Telerik.WinControls.UI.GridViewDataErrorEventArgs e)
{
}
public class Thing
{
private Thing() { }
}
}
To reproduce:
1.Set the GridView template's ViewDefinition to ColumnGroups
2.Add a new column
3.Delete the column
4.Add another new column. The PropertyBuilder closes and it is not possible to open the Smart Tag of RadGridView anymore. Please refer to the attached gif file.
Workaround:
The issue is caused by a remaining reference to a deleted column. When using the RadGridView PropertyBuilder and a column is added to ColumnGroupsViewDefinition, once the column is deleted from RadGridView (via the Property Builder) the code for adding the column in the ColumnGroupsViewDefinition remains, and this causes further designer instability with the Property Builder.
To handle this scenario there are two options:
1. When a column is deleted via Property Builder, and this column was part of ColumnGroupsViewDefinition, open the Designer.cs/vb file, locate the line that adds this column to a ColumnNames collection and delete it. It should be something like:
gridViewColumnGroupRow3.ColumnNames.Add("column1"); - where "column1" is the name of the deleted column
2. Instead of using the Property Builder to build the ColumnGroupsViewDefinition, build it programmatically.
To reproduce:
- Sort the grid and then reset the data source.
- Format the rows like this:
void radGridView1_RowFormatting(object sender, Telerik.WinControls.UI.RowFormattingEventArgs e)
{
string exception_status = "";
string completed_user = "";
if (!DBNull.Value.Equals(e.RowElement.RowInfo.Cells["Name"].Value))
{
exception_status = e.RowElement.RowInfo.Cells["Name"].Value.ToString();
}
if (!DBNull.Value.Equals(e.RowElement.RowInfo.Cells["Drug"].Value))
{
completed_user = e.RowElement.RowInfo.Cells["Drug"].Value.ToString().Trim();
}
if (exception_status == "Sam" && completed_user == "Enebrel")
{
e.RowElement.ForeColor = Color.Red;
}
else
{
e.RowElement.ForeColor = Color.Black;
}
}
Workaround:
if (e.RowElement.RowInfo.Cells.Count ==0)
{
return;
}
Similar property is already available in the property grid and tree view exporters.
To reproduce:
BindingList<Item> items = new BindingList<Item>();
public Form1()
{
InitializeComponent();
for (int i = 0; i < 5; i++)
{
items.Add(new Item(i,i * 1.25m));
}
this.radGridView1.DataSource = items;
this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
GridViewSummaryItem summaryItem = new GridViewSummaryItem();
summaryItem.Name = "Price";
summaryItem.Aggregate = GridAggregateFunction.Sum;
GridViewSummaryRowItem summaryRowItem = new GridViewSummaryRowItem();
summaryRowItem.Add(summaryItem);
this.radGridView1.SummaryRowsTop.Add(summaryRowItem);
this.timer1.Start();
}
public class Item
{
private int id;
private decimal price;
public Item(int id, decimal price)
{
this.id = id;
this.price = price;
}
public int Id
{
get
{
return this.id;
}
set
{
this.id = value;
}
}
public decimal Price
{
get
{
return this.price;
}
set
{
this.price = value;
}
}
}
private void timer1_Tick(object sender, EventArgs e)
{
items[0].Price += 1;
this.radGridView1.Rows[0].InvalidateRow();
this.radGridView1.MasterView.SummaryRows[0].InvalidateRow();
}
Workaround: refresh the MasterTemplate or implement the INotifyPropertyChanged
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;
}
}
To reproduce: - Add 100000 rows to the grid. - Filter the grid so there are no rows. - Call the BestFitColumns method: radGridView1.MasterTemplate.BestFitColumns(Telerik.WinControls.UI.BestFitColumnMode.DisplayedCells) Workaround: If gridview.MasterTemplate.DataView.Count > 0 Then gridview.MasterTemplate.BestFitColumns() End If