I'm getting an exception as follows
System.InvalidOperationException
"Collection was modified; enumeration operation may not execute."
at System.Collections.ArrayList.ArrayListEnumeratorSimple.MoveNext()
at Telerik.WinControls.UI.RadListViewElement.SynchronizeVisualItems()
at Telerik.WinControls.UI.RadListView.OnGotFocus(EventArgs e)
at System.Windows.Forms.Control.WmSetFocus(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at Telerik.WinControls.RadControl.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.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
This occurs when I change selection in my ListView after changing the datasource. So I'm reusing the ListView with different data.
I noticed a thread that I thought might provide a clue (below) but I tried the solution but it didn't work, in fact I got the same exception in that code instead. How can I change the whole datasource in my ListView without exception? Thanks.
https://www.telerik.com/forums/listview--detailview-item-removing
PS: I only noticed this when attempting to highlight text (see my previous thread) and then backing out that code. But perhaps I just didn't notice the issue before.
11 Answers, 1 is accepted
I am not sure how to reproduce this. I have attached my test project. Could you please check it and let me know what I need to change in order to reproduce it.
Thank you in advance for your patience and cooperation.
Regards,
Dimitar
Progress Telerik
I'll try, but actually I've noticed it can happen even after assigning the datasource just once.
Also I'm using custom items and BindingList, e.g. (below, edited)
The exception can occur after just clicking on a single item in the list. I'll try and modify your project to make it happen.
_dataSource = new BindingList<MyVisualItemDef>(); // fieldSomeItems.ForEach(item => _dataSource.Add( new MyVisualItemDef { RuleItemId = item.RuleItemId, Sequence = item.Sequence, Name = item.Name, RuleItemText = GetSomeTextFor(item) }));lstvwRuleItems.DataSource = null;lstvwRuleItems.DataSource = _dataSource;Please find the attached project where the issue occurs.
See comments in method RadForm1.GetRuleItemTextFor()
Keep forgetting I can only post image files... so I'll post the code in code blocks.
class RuleVisualItem
using System;using System.Drawing;using System.Windows.Forms;using Telerik.WinControls.Layouts;using Telerik.WinControls.UI;namespace _1152220{ public class RuleVisualItem : SimpleListViewVisualItem { private RadTextBoxControlElement _idElement; private RadTextBoxControlElement _sequenceElement; private RadTextBoxControlElement _nameElement; private RadTextBoxControlElement _ruleTextElement; private StackLayoutPanel _vStackLayout; private StackLayoutPanel _stackLayout; protected override void CreateChildElements() { base.CreateChildElements(); _stackLayout = new StackLayoutPanel { Orientation = Orientation.Horizontal, ShouldHandleMouseInput = false, NotifyParentOnMouseInput = true }; _vStackLayout = new StackLayoutPanel { Orientation = Orientation.Vertical, ShouldHandleMouseInput = false, NotifyParentOnMouseInput = true }; _sequenceElement = new RadTextBoxControlElement { Text = "", IsReadOnly = true, MinSize = new Size(60, 0) }; _stackLayout.Children.Add(_sequenceElement); _idElement = new RadTextBoxControlElement { Text = "", IsReadOnly = true, MinSize = new Size(60, 0) }; _stackLayout.Children.Add(_idElement); _nameElement = new RadTextBoxControlElement { Text = "", IsReadOnly = true, MinSize = new Size(120, 0), }; _stackLayout.Children.Add(_nameElement); _ruleTextElement = new RadTextBoxControlElement { Text = "", //TextWrap = true, Multiline = true, //IsReadOnly = true, ShouldHandleMouseInput = true, NotifyParentOnMouseInput = false }; _vStackLayout.Children.Add(_stackLayout); _vStackLayout.Children.Add(_ruleTextElement); Children.Add(_vStackLayout); } protected override void SynchronizeProperties() { if (Data == null) return; base.SynchronizeProperties(); Text = ""; // must clear the textboxes or the info in them will be scrambled // https://www.telerik.com/forums/listview-data#fHqS8X47jkumon6G5VPkrQ _idElement.Text = ""; _sequenceElement.Text = ""; _nameElement.Text = ""; _ruleTextElement.Text = ""; _idElement.Text = Convert.ToString(Data["RuleItemId"]); _sequenceElement.Text = Convert.ToString(Data["Sequence"]); _nameElement.Text = Convert.ToString(Data["Name"]); var ruleItemText = Convert.ToString(Data["RuleItemText"]); _ruleTextElement.Text = ruleItemText; } protected override Type ThemeEffectiveType => typeof(SimpleListViewVisualItem); }}
class RuleItemVisualItemDef
using System.ComponentModel;using System.Runtime.CompilerServices;using _1152220.Annotations;namespace _1152220{ public class RuleItemVisualItemDef : INotifyPropertyChanged { private long _ruleItemId; private long _sequence; private string _name; private string _ruleItemText; public long RuleItemId { get { return _ruleItemId; } set { if (value == _ruleItemId) return; _ruleItemId = value; OnPropertyChanged(); } } public long Sequence { get { return _sequence; } set { if (value == _sequence) return; _sequence = value; OnPropertyChanged(); } } public string Name { get { return _name; } set { if (value == _name) return; _name = value; OnPropertyChanged(); } } public string RuleItemText { get { return _ruleItemText; } set { if (value == _ruleItemText) return; _ruleItemText = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; [NotifyPropertyChangedInvocator] protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }}class RadForm1
using System;using System.Collections.Generic;using System.ComponentModel;using System.Text;using Telerik.WinControls.UI;namespace _1152220{ public partial class RadForm1 : Telerik.WinControls.UI.RadForm { private BindingList<RuleItemVisualItemDef> _dataSource; private List<DummyData> _ruleItemDefs; public RadForm1() { InitializeComponent(); lstvwRuleItems.AllowArbitraryItemHeight = true; lstvwRuleItems.AllowEdit = false; lstvwRuleItems.AllowRemove = false; lstvwRuleItems.ViewType = ListViewType.ListView; _ruleItemDefs = new List<DummyData>(); for (int i = 1; i < 5; i++) { _ruleItemDefs.Add( new DummyData { Name = $"Rule {i}", RuleItemId = i * 10, Sequence = i }); } //lstvwRuleItems.ViewType = Telerik.WinControls.UI.ListViewType.DetailsView; //lstvwRuleItems.DataSource = GetTable(); SetViewContents(); } private void SetViewContents() { txtRuleHeading.Text = GetRuleItemHeading(); _dataSource = new BindingList<RuleItemVisualItemDef>(); _ruleItemDefs.ForEach(def => _dataSource.Add( new RuleItemVisualItemDef { RuleItemId = def.RuleItemId, Sequence = def.Sequence, Name = def.Name, RuleItemText = GetRuleItemTextFor(def), })); lstvwRuleItems.DataSource = null; lstvwRuleItems.DataSource = _dataSource; } private string GetRuleItemTextFor(DummyData def) { // this one usually works //return LoremIpsum(minWords: 0, maxWords: 10, minSentences: 1, maxSentences: 5, numParagraphs: 4); // this one usually fails (re-run the app if it doesn't) return LoremIpsum(minWords: 10, maxWords: 30, minSentences: 3, maxSentences: 10, numParagraphs: 4); } private string GetRuleItemHeading() { return "some heading"; } //static DataTable GetTable() //{ // DataTable table = new DataTable(); // table.Columns.Add("bool", typeof(bool)); // table.Columns.Add("Drug", typeof(string)); // table.Columns.Add("Name", typeof(string)); // table.Columns.Add("Date", typeof(DateTime)); // table.Rows.Add(false, "Indocin", "David", DateTime.Now); // table.Rows.Add(false, "Enebrel", "Sam", DateTime.Now); // table.Rows.Add(false, "Hydralazine", "Christoff", DateTime.Now); // table.Rows.Add(false, "Combivent", "Janet", DateTime.Now); // table.Rows.Add(false, "Dilantin", "Melanie", DateTime.Now); // return table; //} //private void radButton1_Click(object sender, EventArgs e) //{ // lstvwRuleItems.DataSource = null; // lstvwRuleItems.DataSource = GetTable(); //} string LoremIpsum(int minWords, int maxWords, int minSentences, int maxSentences, int numParagraphs) { var words = new[]{"lorem", "ipsum", "dolor", "sit", "amet", "consectetuer", "adipiscing", "elit", "sed", "diam", "nonummy", "nibh", "euismod", "tincidunt", "ut", "laoreet", "dolore", "magna", "aliquam", "erat"}; var rand = new Random(); int numSentences = rand.Next(maxSentences - minSentences) + minSentences + 1; int numWords = rand.Next(maxWords - minWords) + minWords + 1; StringBuilder result = new StringBuilder(); for (int p = 0; p < numParagraphs; p++) { result.Append("<p>"); for (int s = 0; s < numSentences; s++) { for (int w = 0; w < numWords; w++) { if (w > 0) { result.Append(" "); } result.Append(words[rand.Next(words.Length)]); } result.Append(". "); } result.Append("</p>"); } return result.ToString(); } private void lstvwRuleItems_VisualItemCreating(object sender, Telerik.WinControls.UI.ListViewVisualItemCreatingEventArgs e) { if (this.lstvwRuleItems.ViewType == ListViewType.ListView) { e.VisualItem = new RuleVisualItem(); } } } internal class DummyData { public long RuleItemId { get; set; } public long Sequence { get; set; } public string Name { get; set; } }}
RadForm1.Designer.cs
namespace _1152220{ partial class RadForm1 { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.txtRuleHeading = new Telerik.WinControls.UI.RadTextBox(); this.lstvwRuleItems = new Telerik.WinControls.UI.RadListView(); ((System.ComponentModel.ISupportInitialize)(this.txtRuleHeading)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.lstvwRuleItems)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this)).BeginInit(); this.SuspendLayout(); // // txtRuleHeading // this.txtRuleHeading.Dock = System.Windows.Forms.DockStyle.Top; this.txtRuleHeading.Location = new System.Drawing.Point(0, 0); this.txtRuleHeading.Name = "txtRuleHeading"; this.txtRuleHeading.Size = new System.Drawing.Size(684, 20); this.txtRuleHeading.TabIndex = 0; // // lstvwRuleItems // this.lstvwRuleItems.Dock = System.Windows.Forms.DockStyle.Fill; this.lstvwRuleItems.Location = new System.Drawing.Point(0, 20); this.lstvwRuleItems.Name = "lstvwRuleItems"; this.lstvwRuleItems.Size = new System.Drawing.Size(684, 456); this.lstvwRuleItems.TabIndex = 1; this.lstvwRuleItems.VisualItemCreating += new Telerik.WinControls.UI.ListViewVisualItemCreatingEventHandler(this.lstvwRuleItems_VisualItemCreating); // // RadForm1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(684, 476); this.Controls.Add(this.lstvwRuleItems); this.Controls.Add(this.txtRuleHeading); this.Name = "RadForm1"; // // // this.RootElement.ApplyShapeToControl = true; this.Text = "RadForm1"; ((System.ComponentModel.ISupportInitialize)(this.txtRuleHeading)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.lstvwRuleItems)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); } #endregion private Telerik.WinControls.UI.RadTextBox txtRuleHeading; private Telerik.WinControls.UI.RadListView lstvwRuleItems; }}I was able to reproduce this exception. It is caused by an issue in our implementation. I have logged this issue on our Feedback Portal. You can track its progress, subscribe to status changes and add your comment to it here. I have also updated your Telerik Points.
You need to inherit the control in order to override the following methods and workaround this issue:
class MyListView : RadListView{ protected override RadListViewElement CreateListViewElement() { return new MyListViewElement(); }}class MyListViewElement : RadListViewElement{ protected override Type ThemeEffectiveType => typeof(RadListViewElement); public override void SynchronizeVisualItems() { for (int i = 0; i < this.ViewElement.ViewElement.Children.Count; i++) { BaseListViewVisualItem visualItem = (BaseListViewVisualItem)this.ViewElement.ViewElement.Children[i]; visualItem.Synchronize(); } this.Invalidate(); }}Should you have any other questions do not hesitate to ask.
Regards,
Dimitar
Progress Telerik
I am glad that this is working fine now. Do not hesitate to contact us if you have other questions.
Regards,
Dimitar
Progress Telerik
Hello, Mordechai,
According to the provided brief information, it is not clear whether you are experiencing any issues with RadListControl in the latest version of the Telerik UI for WinForms suite.I would like to note that the previously referred feedback item has already been fixed. Hence, you are not expected to experience any undesired behavior in the latest version.
However, if you encounter any further difficulties, feel free to submit a support ticket from your Telerik account and provide as much information as possible about the precise case. A sample project would be also greatly appreciated. Thus, we would be able to investigate the precise case and provide further assistance. Thank you in advance.
I hope this information helps. If you need any further assistance please don't hesitate to contact me.
Regards,
Dess | Tech Support Engineer, Sr.
Progress Telerik
Our thoughts here at Progress are with those affected by the outbreak.
Hi Dess,
Firstly, your workaround mentioned earlier for RadListView I followed for RadListControl did in fact fix our issue. Inspecting the Telerik source I did notice the fix in RadListView but not in RadListControl which still uses a foreach loop.
Weirdly enough, the fix unexpectedly affected how the fonts worked in RadTextBoxControlElement. Before the change I had to use the CustomFont to change the font, but after that change I could just use Font
Sorry, I'm not very good at creating demo projects, here's my code:
class RadListControlMod : RadListControl{ protected override RadListElement CreateListElement() { return new RadListElementMod(); }}class RadListElementMod : RadListElement{ protected override Type ThemeEffectiveType => typeof(RadListElement); protected override void SynchronizeVisualItems() { for (var i = 0; i < ViewElement.Children.Count; i++) { var visualItem = (RadListVisualItem)ViewElement.Children[i]; visualItem.Synchronize(); } Invalidate(); }}Hello, Mordechai,
It is still not clear to me what is the exact setup that you have on your end with RadListControl and and what is the exact problem that you are facing. Could you please elaborate?
According to the provided information, it seems that you create a custom RadListControl which in the RadListElement.SynchronizeVisualItems method forces synchronizing the visual items.
Actually, the default implementation executes a similar action. Here is the original source code of the RadListElement:
protected virtual void SynchronizeVisualItems()
{
foreach (RadListVisualItem item in this.ViewElement.Children)
{
item.Synchronize();
}
this.Invalidate();
}This is a code snippet from the latest official version. I am not sure which is the version you are using in your project. Have you tried the default behavior in the latest version? Are you still experiencing any issues?
I would kindly ask you to submit a support ticket from your account and provide a sample project demonstrating the undesired behavior that you are facing. Thus, we would be able to make an adequate analysis of the precise case and think about an appropriate solution. Thank you in advance.
I am looking forward to your reply.
Regards,
Dess | Tech Support Engineer, Sr.
Progress Telerik
Our thoughts here at Progress are with those affected by the outbreak.

