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>();
// field
SomeItems.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.