To reproduce: this.radGridView1.SummaryRowsBottom.Insert(0, summaryRowItem2); this.radGridView1.SummaryRowsBottom.Move(2, 0); Workaround: Remove all items and add them back with a spesific order.
How to reproduce: check the attached project and video
Please refer to the attached sample project and follow the steps illustrated in the gif file. Note: the same behavior is observed with the CellValidating event in the new row. Workaround: use the RowValidating event instead: private void radGridView1_RowValidating(object sender, Telerik.WinControls.UI.RowValidatingEventArgs e) { if (e.Row is Telerik.WinControls.UI.GridViewNewRowInfo && e.Row.Cells["Id"].Value == null) { this.radGridView1.MasterView.TableAddNewRow.CancelAddNewRow(); this.radGridView1.CurrentRow = this.radGridView1.MasterView.TableAddNewRow; } }
NOTE: The CellValidating event is fired multiple times as well when you select a new tab in RadDock. There is a second project attached.
To reproduce:
this.radGridView1.Columns.Add("FIRST CELL ID A");
this.radGridView1.Rows.Add("405-55-214-41763");
this.radGridView1.Rows.Add("405-55-214-46682");
this.radGridView1.Rows.Add("405-55-214-46682");
this.radGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill;
this.radGridView1.MultiSelect = true;
this.radGridView1.SelectionMode = Telerik.WinControls.UI.GridViewSelectionMode.CellSelect;
Please refer to the attached gif file illustrating better the text moving.
Workaround:
private void radGridView1_CellFormatting(object sender, Telerik.WinControls.UI.CellFormattingEventArgs e)
{
e.CellElement.BorderBottomWidth = 2;
e.CellElement.BorderRightWidth = 2;
e.CellElement.BorderTopWidth = 2;
e.CellElement.BorderLeftWidth = 2;
}
The new mode should allow copying of single cells even when having the SelectionMode set to FullRowSelect. The attached project features a possible workaround.
To reproduce: run the attached project and toggle the checkbox in the header cell of the child template.
Workaround: use a custom GridCheckBoxHeaderCellElement
public partial class RadForm1 : Telerik.WinControls.UI.RadForm
{
public RadForm1()
{
InitializeComponent();
this.radGridView1.CreateCell += radGridView1_CreateCell;
DataTable dt = new DataTable();
dt.Columns.Add("CategoryId", typeof(int));
dt.Columns.Add("CategoryName", typeof(string));
dt.Columns.Add("ParentCategoryId", typeof(int));
dt.Rows.Add(1, "Category1", 0);
dt.Rows.Add(2, "Category2", 0);
dt.Rows.Add(3, "Category3", 0);
Random rand = new Random();
for (int i = 4; i < 20; i++)
{
dt.Rows.Add(i, "Category" + i, rand.Next(1, 4));
}
this.radGridView1.Relations.AddSelfReference(this.radGridView1.MasterTemplate, "CategoryId", "ParentCategoryId");
this.radGridView1.DataSource = dt;
this.radGridView1.AutoSizeColumnsMode = Telerik.WinControls.UI.GridViewAutoSizeColumnsMode.Fill;
GridViewTemplate childTemplate = CreateChildTemplate();
GridViewRelation relation = new GridViewRelation(
this.radGridView1.MasterTemplate,
childTemplate);
relation.ChildColumnNames.Add("CategoryId");
relation.ParentColumnNames.Add("CategoryId");
this.radGridView1.Relations.Add(relation);
}
private void radGridView1_CreateCell(object sender, GridViewCreateCellEventArgs e)
{
if (e.CellType == typeof(GridCheckBoxHeaderCellElement))
{
e.CellElement = new CustomGridCheckBoxHeaderCellElement(e.Column, e.Row);
}
}
private GridViewTemplate CreateChildTemplate()
{
GridViewTemplate childTemplate = new GridViewTemplate();
childTemplate.AutoGenerateColumns = false;
this.radGridView1.Templates.Add(childTemplate);
GridViewDecimalColumn decColumn = new GridViewDecimalColumn
{
Name = "CategoryId",
HeaderText = "CategoryId Id",
FieldName = "CategoryId",
IsVisible = false,
MinWidth = 100
};
childTemplate.Columns.Add(decColumn);
GridViewTextBoxColumn tbxColumn = new GridViewTextBoxColumn
{
Name = "RightName",
HeaderText = "Right Name",
FieldName = "RGT_NAME",
ReadOnly = true,
MinWidth = 100
};
childTemplate.Columns.Add(tbxColumn);
GridViewCheckBoxColumn chkxColumn = new GridViewCheckBoxColumn
{
Name = "Checkbox",
EnableHeaderCheckBox = true,
FieldName = "HasAccess",
};
childTemplate.Columns.Add(chkxColumn);
childTemplate.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
return childTemplate;
}
public class CustomGridCheckBoxHeaderCellElement : GridCheckBoxHeaderCellElement
{
public CustomGridCheckBoxHeaderCellElement(GridViewColumn column, GridRowElement row) : base(column, row)
{
}
public bool SuspendProcessingToggleStateChanged
{
get
{
FieldInfo fi = typeof(GridCheckBoxHeaderCellElement).GetField("suspendProcessingToggleStateChanged", BindingFlags.NonPublic | BindingFlags.Instance);
return (bool)fi.GetValue(this);
}
set
{
FieldInfo fi = typeof(GridCheckBoxHeaderCellElement).GetField("suspendProcessingToggleStateChanged", BindingFlags.NonPublic | BindingFlags.Instance);
fi.SetValue(this, value);
}
}
public bool ShouldCheckDataRows
{
get
{
FieldInfo fi = typeof(GridCheckBoxHeaderCellElement).GetField("shouldCheckDataRows", BindingFlags.NonPublic | BindingFlags.Instance);
return (bool)fi.GetValue(this);
}
set
{
FieldInfo fi = typeof(GridCheckBoxHeaderCellElement).GetField("shouldCheckDataRows", BindingFlags.NonPublic | BindingFlags.Instance);
fi.SetValue(this, value);
}
}
protected override void checkbox_ToggleStateChanged(object sender, StateChangedEventArgs args)
{
if (SuspendProcessingToggleStateChanged)
{
return;
}
if (this.ViewTemplate != null && !this.ViewTemplate.IsSelfReference && !this.MasterTemplate.IsSelfReference)
{
this.MasterTemplate.BeginUpdate();
}
else
{
this.TableElement.BeginUpdate();
}
object valueState = DBNull.Value;
if (args.ToggleState == ToggleState.On)
{
valueState = true;
}
else if (args.ToggleState == ToggleState.Off)
{
valueState = false;
}
else if (args.ToggleState == ToggleState.Indeterminate)
{
valueState = null;
}
RaiseToggleStateEvent();
if (!ShouldCheckDataRows)
{
if (this.ViewTemplate != null && !this.ViewTemplate.IsSelfReference && !this.MasterTemplate.IsSelfReference)
{
this.MasterTemplate.EndUpdate(true, new DataViewChangedEventArgs(ViewChangedAction.DataChanged));
}
return;
}
this.GridViewElement.EditorManager.EndEdit();
this.TableElement.BeginUpdate();
this.MasterTemplate.MasterViewInfo.TableSearchRow.SuspendSearch();
List<GridViewRowInfo> list = GetRowsToIterateOver();
foreach (GridViewRowInfo rowInfo in list)
{
GridViewGroupRowInfo groupRow = rowInfo as GridViewGroupRowInfo;
if (groupRow != null)
{
this.CheckAllCheckBoxInChildRows(groupRow, valueState);
}
else
{
rowInfo.Cells[this.ColumnIndex].Value = valueState;
}
}
this.MasterTemplate.MasterViewInfo.TableSearchRow.ResumeSearch();
this.TableElement.EndUpdate(false);
if (this.ViewTemplate != null && !this.ViewTemplate.IsSelfReference && !this.MasterTemplate.IsSelfReference)
{
this.MasterTemplate.EndUpdate(true, new DataViewChangedEventArgs(ViewChangedAction.DataChanged));
}
else
{
this.TableElement.EndUpdate(false);
}
this.TableElement.Update(GridUINotifyAction.DataChanged);
}
private void CheckAllCheckBoxInChildRows(GridViewGroupRowInfo row, object state)
{
List<GridViewRowInfo> list = new List<GridViewRowInfo>();
foreach (GridViewRowInfo rowInfo in row.ChildRows)
{
list.Add(rowInfo);
}
foreach (GridViewRowInfo rowInfo in list)
{
GridViewGroupRowInfo groupInfo = rowInfo as GridViewGroupRowInfo;
if (groupInfo != null)
{
this.CheckAllCheckBoxInChildRows(groupInfo, state);
}
else
{
rowInfo.Cells[this.ColumnIndex].Value = state;
}
}
}
private List<GridViewRowInfo> GetRowsToIterateOver()
{
if (this.ViewTemplate != null && this.ViewTemplate.IsSelfReference)
{
PrintGridTraverser traverser = new PrintGridTraverser(this.ViewInfo);
List<GridViewRowInfo> result = new List<GridViewRowInfo>();
while (traverser.MoveNext())
{
if (traverser.Current is GridViewDataRowInfo)
{
result.Add(traverser.Current);
}
}
return result;
}
return new List<GridViewRowInfo>(this.ViewInfo.Rows);
}
}
}
Currently the time for opening the popup for a column with 100 000 unique items including blank items is about 8s, this can be optimized.
How to reproduce:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.radGridView1.EnableFiltering = true;
this.radGridView1.ShowHeaderCellButtons = true;
this.radGridView1.DataSource = this.GetData();
this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
this.radGridView1.MouseDown += RadGridView1_MouseDown;
this.radGridView1.FilterPopupInitialized += RadGridView1_FilterPopupInitialized;
}
Stopwatch sw = new Stopwatch();
private void RadGridView1_MouseDown(object sender, MouseEventArgs e)
{
GridFilterButtonElement btn = this.radGridView1.ElementTree.GetElementAtPoint(e.Location) as GridFilterButtonElement;
if (btn != null)
{
sw.Start();
}
}
private void RadGridView1_FilterPopupInitialized(object sender, FilterPopupInitializedEventArgs e)
{
((RadListFilterPopup)e.FilterPopup).PopupOpened += Form1_PopupOpened;
}
private void Form1_PopupOpened(object sender, EventArgs args)
{
sw.Stop();
Console.WriteLine("Total: " + sw.ElapsedMilliseconds);
}
private DataTable GetData()
{
DataTable dt = new DataTable();
dt.Columns.Add("Id", typeof(int));
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Date", typeof(DateTime));
dt.Columns.Add("Bool", typeof(bool));
for (int i = 0; i < 100000; i++)
{
dt.Rows.Add(i, "Name " + i, DateTime.Now.AddDays(i), i % 2 == 0);
}
dt.Rows.Add(1, null, DateTime.Now.AddDays(1), false);
return dt;
}
}
How to reproduce: check also the attached video
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.radGridView1.DataSource = this.GetData();
this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
GroupDescriptor descriptor = new GroupDescriptor();
descriptor.GroupNames.Add("Name", ListSortDirection.Ascending);
this.radGridView1.GroupDescriptors.Add(descriptor);
}
private DataTable GetData()
{
DataTable dt = new DataTable();
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Age", typeof(int));
dt.Columns.Add("Date", typeof(DateTime));
dt.Columns.Add("Bool", typeof(bool));
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 60; j++)
{
dt.Rows.Add("Name " + i, i, DateTime.Now.AddDays(i), i % 2 == 0);
}
}
return dt;
}
private void radButton1_Click(object sender, EventArgs e)
{
GridPrintStyle style = new GridPrintStyle();
style.FitWidthMode = PrintFitWidthMode.FitPageWidth;
this.radGridView1.PrintStyle = style;
RadPrintDocument doc = new RadPrintDocument();
doc.HeaderHeight = 30;
doc.HeaderFont = new Font("Arial", 12);
doc.LeftHeader = "Left Header";
doc.MiddleHeader = "Middle header";
doc.RightHeader = "Right header";
doc.AssociatedObject = this.radGridView1;
RadPrintPreviewDialog dialog = new RadPrintPreviewDialog(doc);
dialog.Show();
}
}
Workaround: create a custom GridPrintStyle class
public class MyGridPrintStyle : GridPrintStyle
{
protected override BaseGridPrintRenderer InitializePrintRenderer(RadGridView grid)
{
BaseGridPrintRenderer rend = base.InitializePrintRenderer(grid);
if (rend is TableViewDefinitionPrintRenderer)
{
return new MyTableViewDefinitionPrintRenderer(grid);
}
return rend;
}
}
public class MyTableViewDefinitionPrintRenderer : TableViewDefinitionPrintRenderer
{
public MyTableViewDefinitionPrintRenderer(RadGridView grid)
: base(grid)
{
}
protected override void PrintRowWideCell(GridViewRowInfo row, TableViewRowLayout rowLayout, GridPrintSettings settings, int currentX, int currentY, Graphics graphics)
{
int groupLevel = row.Group != null ? row.Group.Level + 1 : 0;
int indentLevel = row.HierarchyLevel + 1 - groupLevel;
Size cellSize = this.GetRowSize(row, rowLayout);
int cellX = currentX + indentLevel * settings.HierarchyIndent + rowLayout.Owner.CellSpacing;
Rectangle cellRect = new Rectangle(cellX, currentY, cellSize.Width - indentLevel * settings.HierarchyIndent, cellSize.Height);
CellPrintElement printCell = new CellPrintElement();
if (row is GridViewGroupRowInfo)
{
if (this.PrintPages.Count > 0 && !settings.PrintHierarchy)
{
cellRect.Width -= this.PrintPages[this.CurrentPrintPage].Count - 1;
}
printCell = this.CreateGroupCellPrintElement(row as GridViewGroupRowInfo);
if (printCell.Font != settings.GroupRowFont)
{
if (settings.GroupRowFont != null)
{
printCell.Font = settings.GroupRowFont;
}
else
{
settings.GroupRowFont = printCell.Font;
}
}
}
printCell.TextPadding = this.GridView.PrintStyle.CellPadding;
printCell.RightToLeft = this.GridView.RightToLeft == RightToLeft.Yes;
PrintCellFormattingEventArgs formattEventArgs = new PrintCellFormattingEventArgs(row, null, printCell);
this.OnPrintCellFormatting(formattEventArgs);
PrintCellPaintEventArgs paintEventArgs = new PrintCellPaintEventArgs(graphics, row, null, cellRect);
this.OnPrintCellPaint(paintEventArgs);
formattEventArgs.PrintCell.Paint(graphics, paintEventArgs.CellRect);
}
}
How to reproduce: check the attached video
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.radGridView1.DataSource = this.GetData(1000);
this.radGridView1.AutoExpandGroups = true;
this.radGridView1.EnableFiltering = true;
this.radGridView1.EnablePaging = true;
this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
}
private DataTable GetData(int count)
{
DataTable dt = new DataTable();
dt.Columns.Add("Id", typeof(int));
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Date", typeof(DateTime));
dt.Columns.Add("Bool", typeof(bool));
for (int i = 0; i < count; i++)
{
dt.Rows.Add(i,"Name " + i, DateTime.Now.AddDays(i), i % 2 == 0 ? true : false);
}
return dt;
}
}
Workaround: cancel the PageChanging event
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.radGridView1.DataSource = this.GetData(1000);
this.radGridView1.AutoExpandGroups = true;
this.radGridView1.EnableFiltering = true;
this.radGridView1.EnablePaging = true;
this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
timer = new Timer();
timer.Interval = 100;
timer.Tick += (sender, e) =>
{
timer.Stop();
this.shouldCancel = false;
};
this.radGridView1.PageChanging += RadGridView1_PageChanging;
this.radGridView1.CurrentRowChanged += RadGridView1_CurrentRowChanged;
}
private void RadGridView1_CurrentRowChanged(object sender, CurrentRowChangedEventArgs e)
{
this.shouldCancel = this.ShouldCancelPageChange(e.CurrentRow);
timer.Start();
}
Timer timer;
bool shouldCancel = false;
private bool ShouldCancelPageChange(GridViewRowInfo rowInfo)
{
if (this.radGridView1.TableElement.MasterTemplate != null && this.radGridView1.TableElement.MasterTemplate.EnablePaging)
{
int pageIndex = this.radGridView1.TableElement.ViewTemplate.DataView.GetItemPage(rowInfo);
if (pageIndex == this.radGridView1.TableElement.MasterTemplate.PageIndex)
{
return true;
}
}
return false;
}
private void RadGridView1_PageChanging(object sender, Telerik.WinControls.PageChangingEventArgs e)
{
e.Cancel = this.shouldCancel;
}
private DataTable GetData(int count)
{
DataTable dt = new DataTable();
dt.Columns.Add("Id", typeof(int));
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Date", typeof(DateTime));
dt.Columns.Add("Bool", typeof(bool));
for (int i = 0; i < count; i++)
{
dt.Rows.Add(i,"Name " + i, DateTime.Now.AddDays(i), i % 2 == 0 ? true : false);
}
return dt;
}
}
I have a GridView (Winforms v. 2017.3.1017.40, same problem with 2017.2.502.40) configured as on the attached screenshot (made some groups, made a search, and used the "excel-like" filter on a column to uncheck some values). Then I try to click on some column headers to sort the grid. After a few clicks, I get this error : InvalidOperationException: La collection a été modifiée ; l'opération d'énumération peut ne pas s'exécuter. I got different stacktrace with the same error : InvalidOperationException: La collection a été modifiée ; l'opération d'énumération peut ne pas s'exécuter. at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource) at System.Collections.Generic.List`1.Enumerator.MoveNextRare() at System.Collections.Generic.List`1.Enumerator.MoveNext() at Telerik.WinControls.UI.DataGroup.<GetEnumerator>d__0.MoveNext() at Telerik.WinControls.UI.GridViewGroupRowInfo.get_ChildRows() at Telerik.WinControls.UI.GridViewRowInfo.HasChildRows() at Telerik.WinControls.UI.PrintGridTraverser.CanStepInHierarchy() at Telerik.WinControls.UI.GridTraverser.StepInHierarchy() at Telerik.WinControls.UI.GridTraverser.MoveNextCore() at Telerik.WinControls.UI.GridTraverser.MoveNext() at Telerik.WinControls.UI.GridViewSearchRowInfo.worker_DoWork(Object sender, DoWorkEventArgs e) at System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e) at System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object argument) ----- InvalidOperationException: Failed to compare two elements in the array. ---> NullReferenceException: Object reference not set to an instance of an object. at Telerik.WinControls.UI.GridViewRowInfoComparer.CompareRows(GridViewRowInfo x, GridViewRowInfo y, SortDescriptorCollection context) at System.Collections.Generic.ArraySortHelper`1.InternalBinarySearch(T[] array, Int32 index, Int32 length, T value, IComparer`1 comparer) at System.Collections.Generic.ArraySortHelper`1.BinarySearch(T[] array, Int32 index, Int32 length, T value, IComparer`1 comparer) --- End of inner exception stack trace --- at System.Collections.Generic.ArraySortHelper`1.BinarySearch(T[] array, Int32 index, Int32 length, T value, IComparer`1 comparer) at System.Collections.Generic.List`1.BinarySearch(Int32 index, Int32 count, T item, IComparer`1 comparer) at Telerik.Collections.Generic.HybridIndex`1.PerformWithQuickSort() at Telerik.Collections.Generic.HybridIndex`1.get_Items() at Telerik.Collections.Generic.Index`1.GetEnumerator() at Telerik.WinControls.Data.GroupBuilder`1.Perform(IReadOnlyCollection`1 items, Int32 level, Group`1 parent) at Telerik.WinControls.Data.GroupBuilder`1.get_Groups() at Telerik.WinControls.UI.GridViewInfo.Refresh() at Telerik.WinControls.UI.GridViewInfo.get_ChildRows() at Telerik.WinControls.UI.ViewInfoTraverser.SetCollectionForStage(Boolean initializeCollection) at Telerik.WinControls.UI.ViewInfoTraverser.ChangeCollectionForward() at Telerik.WinControls.UI.ViewInfoTraverser.MoveNextCore() at Telerik.WinControls.UI.ViewInfoTraverser.MoveNext() at Telerik.WinControls.UI.GridTraverser.MoveNextCore() at Telerik.WinControls.UI.GridTraverser.MoveNext() at Telerik.WinControls.UI.BaseGridNavigator.NavigateToRow(GridViewRowInfo row, Boolean select) at Telerik.WinControls.UI.BaseGridNavigator.ProcessViewChangedEvent(GridViewEvent eventData) at Telerik.WinControls.UI.BaseGridNavigator.ProcessEventCore(GridViewEvent eventData) at Telerik.WinControls.UI.GridViewEventProcessEntity.ProcessCollection(GridViewEvent gridEvent, PriorityWeakReferenceList list, GridEventProcessMode processMode) at Telerik.WinControls.UI.GridViewEventProcessEntity.ProcessEvent(GridViewEvent gridEvent) at Telerik.WinControls.UI.GridViewSynchronizationService.NotifyListeners(GridViewEvent gridEvent) at Telerik.WinControls.UI.GridViewSynchronizationService.FlushEvents() at Telerik.WinControls.UI.GridViewSynchronizationService.DispatchEvent(GridViewEvent gridEvent) at Telerik.WinControls.UI.GridViewSynchronizationService.DispatchEvent(GridViewTemplate template, GridViewEvent eventData, Boolean postUI) at Telerik.WinControls.UI.GridViewTemplate.DispatchDataViewChangedEvent(Object sender, DataViewChangedEventArgs args) at Telerik.WinControls.UI.GridViewTemplate.OnViewChanged(Object sender, DataViewChangedEventArgs e) at Telerik.WinControls.UI.MasterGridViewTemplate.OnViewChanged(Object sender, DataViewChangedEventArgs e) at Telerik.WinControls.Data.RadDataView`1.RebuildData(Boolean notify) at Telerik.WinControls.Data.RadDataView`1.OnNotifyPropertyChanged(PropertyChangedEventArgs e) at Telerik.WinControls.Data.RadCollectionView`1.OnNotifyPropertyChanged(String propertyName) at Telerik.WinControls.UI.GridViewSortDescriptorCollection.OnCollectionChanged(NotifyCollectionChangedEventArgs args) at System.ComponentModel.PropertyChangedEventHandler.Invoke(Object sender, PropertyChangedEventArgs e) at Telerik.WinControls.Data.SortDescriptor.set_Direction(ListSortDirection value) at Telerik.WinControls.UI.GridViewColumn.Sort(RadSortOrder sortOrder, Boolean multiSortMode) at Telerik.WinControls.UI.GridHeaderCellElement.Sort(RadSortOrder sortOrder) at Telerik.WinControls.UI.GridHeaderRowBehavior.OnMouseUp(MouseEventArgs e) at Telerik.WinControls.UI.BaseGridBehavior.OnMouseUp(MouseEventArgs e) at Telerik.WinControls.UI.RadGridView.OnMouseUp(MouseEventArgs e) at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) at System.Windows.Forms.Control.WndProc(Message& m) at Telerik.WinControls.RadControl.WndProc(Message& m) at Telerik.WinControls.UI.RadGridView.WndProc(Message& m) at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) ------ InvalidOperationException: Collection was modified; enumeration operation may not execute. at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource) at System.Collections.Generic.List`1.Enumerator.MoveNextRare() at System.Collections.Generic.List`1.Enumerator.MoveNext() at Telerik.WinControls.UI.DataGroup.<GetEnumerator>d__0.MoveNext() [...] at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) at Alto.Client.Controls.Dispatch.DispatchResources.DeliveryPointFilterManager.get_DeliveryPointsVisible() in d:\Builds\45153\Alto\Alto.Prod\src\Alto\Alto.Client\Controls\Dispatch\DispatchResources\DeliveryPointFilterManager.cs:line 38 at Alto.Client.Controls.Dispatch.DispatchResources.UcDeliveryPoint.get_Title() in d:\Builds\45153\Alto\Alto.Prod\src\Alto\Alto.Client\Controls\Dispatch\DispatchResources\UcDeliveryPoint.cs:line 1520 at Alto.Client.Controls.Dispatch.DispatchResources.UcDeliveryPoint.updatePanelTitle() in d:\Builds\45153\Alto\Alto.Prod\src\Alto\Alto.Client\Controls\Dispatch\DispatchResources\UcDeliveryPoint.cs:line 543 at Alto.Client.Controls.Dispatch.DispatchResources.UcDeliveryPoint.onFilterChanged(Object sender, GridViewCollectionChangedEventArgs e) in d:\Builds\45153\Alto\Alto.Prod\src\Alto\Alto.Client\Controls\Dispatch\DispatchResources\UcDeliveryPoint.cs:line 547 at Telerik.WinControls.UI.GridViewCollectionChangedEventHandler.Invoke(Object sender, GridViewCollectionChangedEventArgs e) at Telerik.WinControls.UI.RadGridView.OnFilterChanged(Object sender, GridViewCollectionChangedEventArgs e) at Telerik.WinControls.UI.EventDispatcher.RaiseEvent[T](Object eventKey, Object sender, T args) at Telerik.WinControls.UI.GridViewFilterDescriptorCollection.OnCollectionChanged(NotifyCollectionChangedEventArgs args) at Telerik.Collections.Generic.NotifyCollection`1.InsertItem(Int32 index, T item) at Telerik.WinControls.UI.GridViewFilterDescriptorCollection.InsertItem(Int32 index, FilterDescriptor item) at System.Collections.ObjectModel.Collection`1.Add(T item) at Telerik.WinControls.UI.GridViewDataColumn.SetFilterDescriptor(FilterDescriptor value) at Telerik.WinControls.UI.GridHeaderCellElement.filterPopup_FilterConfirmed(Object sender, EventArgs e) at Telerik.WinControls.UI.BaseFilterPopup.OnFilterConfirmed() at Telerik.WinControls.UI.RadListFilterPopup.OnButtonOkClick(EventArgs e) at Telerik.WinControls.UI.RadListFilterPopup.ButtonOK_Click(Object sender, EventArgs e) at Telerik.WinControls.RadElement.OnClick(EventArgs e) at Telerik.WinControls.UI.RadButtonItem.OnClick(EventArgs e) at Telerik.WinControls.UI.RadButtonElement.OnClick(EventArgs e) at Telerik.WinControls.RadElement.DoClick(EventArgs e) at Telerik.WinControls.RadElement.RaiseBubbleEvent(RadElement sender, RoutedEventArgs args) at Telerik.WinControls.RadItem.RaiseBubbleEvent(RadElement sender, RoutedEventArgs args) at Telerik.WinControls.RadElement.RaiseRoutedEvent(RadElement sender, RoutedEventArgs args) at Telerik.WinControls.RadElement.RaiseBubbleEvent(RadElement sender, RoutedEventArgs args) at Telerik.WinControls.RadItem.RaiseBubbleEvent(RadElement sender, RoutedEventArgs args) at Telerik.WinControls.RadElement.RaiseRoutedEvent(RadElement sender, RoutedEventArgs args) at Telerik.WinControls.RadElement.DoMouseUp(MouseEventArgs e) at Telerik.WinControls.ComponentInputBehavior.OnMouseUp(MouseEventArgs e) at Telerik.WinControls.RadControl.OnMouseUp(MouseEventArgs e) at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.ScrollableControl.WndProc(Message& m) at Telerik.WinControls.RadControl.WndProc(Message& m) at Telerik.WinControls.UI.RadPopupControlBase.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) ---- InvalidOperationException: Collection was modified; enumeration operation may not execute. at System.Collections.Generic.List`1.Enumerator.MoveNextRare() at Telerik.WinControls.UI.DataGroup.<GetEnumerator>d__0.MoveNext() at Telerik.WinControls.Data.GroupBuilder`1.Perform(IReadOnlyCollection`1 items, Int32 level, Group`1 parent) at Telerik.WinControls.Data.DataItemGroup`1.get_Groups() at Telerik.WinControls.UI.DataGroup.get_Groups() at Telerik.WinControls.UI.GridViewTemplate.InvalidateSummaryRowsCore(DataGroup group, Boolean invalidateChildren) at Telerik.WinControls.UI.GridViewTemplate.InvalidateSummaryRowsCore(DataGroup group, Boolean invalidateChildren) at Telerik.WinControls.UI.GridViewTemplate.InvalidateGroupSummaryRows(DataGroup group, Boolean invalidateChildren) at Telerik.WinControls.UI.GridViewTemplate.RefreshSummaryRowsInGroup(NotifyCollectionChangedEventArgs e) at Telerik.WinControls.UI.GridViewTemplate.RefreshAggregates(NotifyCollectionChangedEventArgs e) at Telerik.WinControls.UI.MasterGridViewTemplate.OnViewChanged(Object sender, DataViewChangedEventArgs e) at Telerik.WinControls.Data.RadDataView`1.RebuildData(Boolean notify) at Telerik.WinControls.Data.RadDataView`1.OnNotifyPropertyChanged(PropertyChangedEventArgs e) at Telerik.WinControls.Data.RadCollectionView`1.OnNotifyPropertyChanged(String propertyName) at Telerik.WinControls.UI.GridViewSortDescriptorCollection.OnCollectionChanged(NotifyCollectionChangedEventArgs args) at Telerik.WinControls.UI.GridViewSortDescriptorCollection.RemoveItem(Int32 index) at Telerik.WinControls.UI.GridViewColumn.Sort(RadSortOrder sortOrder, Boolean multiSortMode) at Telerik.WinControls.UI.GridHeaderCellElement.Sort(RadSortOrder sortOrder) at Telerik.WinControls.UI.GridHeaderRowBehavior.OnMouseUp(MouseEventArgs e) at Telerik.WinControls.UI.BaseGridBehavior.OnMouseUp(MouseEventArgs e) at Telerik.WinControls.UI.RadGridView.OnMouseUp(MouseEventArgs e) at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) at System.Windows.Forms.Control.WndProc(Message& m) at Telerik.WinControls.RadControl.WndProc(Message& m) at Telerik.WinControls.UI.RadGridView.WndProc(Message& m) at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
To reproduce: please refer to the attached gif file and sample project.
Workaround:
private void radGridView1_CellEndEdit(object sender, GridViewCellEventArgs e)
{
RadDropDownListEditor editor = e.ActiveEditor as RadDropDownListEditor;
if (editor!=null)
{
RadDropDownListEditorElement el = editor.EditorElement as RadDropDownListEditorElement;
el.AutoCompleteSuggest.DropDownList.ClosePopup();
}
}
To reproduce:
Sub New()
InitializeComponent()
Dim dt As New DataTable
dt.Columns.Add("Id", GetType(Integer))
dt.Columns.Add("Name", GetType(String))
For index = 1 To 1000
dt.Rows.Add(index, "Item" & index)
Next
Me.RadGridView1.DataSource = dt
End Sub
Private Sub RadButton1_Click(sender As Object, e As EventArgs) Handles RadButton1.Click
Dim pdfFile As String = "..\..\exportedFile.pdf"
Dim pdfExporter As New GridViewPdfExport(Me.RadGridView1)
pdfExporter.ShowHeaderAndFooter = True
pdfExporter.FitToPageWidth = True
AddHandler pdfExporter.PdfExported, AddressOf pdfExporter_PdfExported
Dim renderer As New PdfExportRenderer()
pdfExporter.RunExport(pdfFile, renderer)
Process.Start(pdfFile)
End Sub
Private Sub pdfExporter_PdfExported(sender As Object, e As System.EventArgs)
Dim pdfFile As String = "..\..\exportedFile.pdf"
Dim document As RadFixedDocument
Dim provider As Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.PdfFormatProvider = New Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.PdfFormatProvider()
Using stream As Stream = File.OpenRead(pdfFile)
document = provider.Import(stream) '<==== Error Found
For Each page As RadFixedPage In document.Pages
Dim editor As FixedContentEditor = New FixedContentEditor(page)
editor.Position.Translate(page.Size.Width / 2, page.Size.Height - 50)
Dim pageNum As Integer = document.Pages.IndexOf(page) + 1
editor.DrawText(pageNum + " of " + document.Pages.Count)
Next
End Using
Using output As Stream = File.OpenWrite(pdfFile)
provider.Export(document, output) '<==== Error Found
End Using
Process.Start(pdfFile)
End Sub
Workaround: use the PdfExportRenderer.PdfExporting event where you have access to the document and you can make any customizations to it:
Dim pdfFile As String = "..\..\exportedFile.pdf"
Dim pdfExporter As New GridViewPdfExport(Me.RadGridView1)
pdfExporter.ShowHeaderAndFooter = True
pdfExporter.FitToPageWidth = True
Dim renderer As New PdfExportRenderer()
AddHandler renderer.PdfExporting, AddressOf PdfExporting
pdfExporter.RunExport(pdfFile, renderer)
Private Sub PdfExporting(sender As Object, e As PdfExportingEventArgs)
Dim document As RadFixedDocument = e.Document
Dim provider As Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.PdfFormatProvider = New Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.PdfFormatProvider()
For Each page As RadFixedPage In document.Pages
Dim editor As FixedContentEditor = New FixedContentEditor(page)
editor.Position.Translate(page.Size.Width / 2, page.Size.Height - 50)
Dim pageNum As Integer = document.Pages.IndexOf(page) + 1
editor.DrawText(pageNum & " of " & document.Pages.Count)
Next
End Sub
To reproduce: run the project, select the grid and press Tab. You will notice a message box for the first grid which won't be shown for the second in the popup.
Use attached to reproduce.
Workaround:
class MyGridCheckBoxHeaderCellElement : GridCheckBoxHeaderCellElement
{
public MyGridCheckBoxHeaderCellElement(GridRowElement row, GridViewColumn col) : base(col, row)
{
}
bool suspenUpdate = false;
protected override void checkbox_ToggleStateChanged(object sender, StateChangedEventArgs args)
{
suspenUpdate = true;
base.checkbox_ToggleStateChanged(sender, args);
suspenUpdate = false;
}
protected override void SetCheckBoxState()
{
if (!suspenUpdate)
{
base.SetCheckBoxState();
}
}
}
private void RadGridView1_CreateCell(object sender, GridViewCreateCellEventArgs e)
{
if (e.Column != null&& e.CellType == typeof(GridCheckBoxHeaderCellElement))
{
e.CellElement = new MyGridCheckBoxHeaderCellElement(e.Row, e.Column);
}
}
In self-reference if you bind the grid to a record having is ParentId the same as its Id, the grid will try to create a row which is parented by itself. This is not valid input data and we should throw a proper exception, otherwise the application will freeze.
How to reproduce:
public partial class Form2 : Form
{
private BindingList<DataObject> data;
public Form2()
{
InitializeComponent();
this.radGridView1.AutoGenerateHierarchy = true;
this.data = new BindingList<DataObject>();
int count = 10;
for (int i = 0; i < count; i++)
{
DataObject p = new DataObject();
p.Id = i;
p.Name = "Parent " + i;
this.data.Add(p);
for (int j = 0; j < count; j++)
{
DataObject c = new DataObject();
c.Id = count + j + i * count;
c.Name = "Child " + i;
c.ParentId = i;
this.data.Add(c);
}
}
this.radButton1.Click += RadButton1_Click;
}
private void RadButton1_Click(object sender, EventArgs e)
{
if (this.radGridView1.Relations.Count > 0)
{
this.radGridView1.Relations.Clear();
}
this.radGridView1.DataSource = this.data;
this.radGridView1.Relations.AddSelfReference(this.radGridView1.MasterTemplate, "Id", "ParentId");
}
}
public class DataObject
{
public int Id { get; set; }
public string Name { get; set; }
public int ParentId { get; set; }
}
Workaround: set the ParentId of the parent records
int count = 10;
for (int i = 0; i < count; i++)
{
DataObject p = new DataObject();
p.Id = i;
p.Name = "Parent " + i;
p.ParentId = -1;
this.data.Add(p);
for (int j = 0; j < count; j++)
{
DataObject c = new DataObject();
c.Id = count + j + i * count;
c.Name = "Child " + i;
c.ParentId = i;
this.data.Add(c);
}
}
How to reproduce: check the code snippet below and the attached video.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.SetupGrid();
this.radGridView1.Dock = DockStyle.Fill;
this.radGridView1.UseScrollbarsInHierarchy = true;
}
private void SetupGrid()
{
BindingList<Teacher> teachers = new BindingList<Teacher>();
BindingList<Student> students = new BindingList<Student>();
for (int i = 1; i <= 2; i++)
{
teachers.Add(new Teacher
{
TeacherId = i,
TeacherFirstName = "FirstName " + i,
TeacherLastName = "FirstName " + i,
});
for (int j = 1; j <= 3; j++)
{
students.Add(new Student
{
SudentId = j,
TeacherId = i,
SudentFirstName = "Student " + j,
SudentLastName = "LastName " + j,
});
}
}
this.radGridView1.Templates.Clear();
this.radGridView1.DataSource = null;
this.radGridView1.DataSource = teachers;
this.radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
GridViewTemplate template = new GridViewTemplate();
template.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
template.DataSource = students;
this.radGridView1.MasterTemplate.Templates.Add(template);
GridViewRelation relation = new GridViewRelation(radGridView1.MasterTemplate);
relation.ChildTemplate = template;
relation.RelationName = "TeacherStudents";
relation.ParentColumnNames.Add("TeacherId");
relation.ChildColumnNames.Add("TeacherId");
this.radGridView1.Relations.Add(relation);
this.radGridView1.ChildViewExpanded += RadGridView1_ChildViewExpanded1;
}
private void RadGridView1_ChildViewExpanded1(object sender, ChildViewExpandedEventArgs e)
{
}
private void radButton1_Click(object sender, EventArgs e)
{
this.radGridView1.SaveLayout("..\\..\\save.xml");
}
private void radButton2_Click(object sender, EventArgs e)
{
this.radGridView1.LoadLayout("..\\..\\save.xml");
}
}
public class Teacher
{
public int TeacherId { get; set; }
public string TeacherFirstName { get; set; }
public string TeacherLastName { get; set; }
}
public class Student
{
public int SudentId { get; set; }
public int TeacherId { get; set; }
public string SudentFirstName { get; set; }
public string SudentLastName { get; set; }
}
Workaround: prevent the child templates from serializing
public class MyRadGridView : RadGridView
{
public override string ThemeClassName
{
get
{
return typeof(RadGridView).FullName;
}
}
public override void SaveLayout(string fileName)
{
MyGridViewLayoutSerializer ser = new MyGridViewLayoutSerializer(this.XmlSerializationInfo);
using (XmlTextWriter writer = new XmlTextWriter(fileName, Encoding.UTF8))
{
writer.Formatting = Formatting.Indented;
writer.WriteStartElement("RadGridView");
ser.WriteObjectElement(writer, this);
}
}
}
public class MyGridViewLayoutSerializer : GridViewLayoutSerializer
{
public MyGridViewLayoutSerializer(ComponentXmlSerializationInfo componentSerializationInfo)
: base(componentSerializationInfo)
{ }
protected override bool ShouldSerializeValue(object component, PropertyDescriptor property, PropertySerializationMetadata overwriteMetadata)
{
if (property.Name == "Templates")
{
return false;
}
return base.ShouldSerializeValue(component, property, overwriteMetadata);
}
}
To reproduce: please refer to the attached gif file and sample project Workaround: set the AutoSizeRows property to false