I'm new to winforms, I've used silverlight a lot in last 2 years... I was wondering why a simple thing I do in SL it seems to me so complicated here. ..
I got a class defined as
public class RapportoItem : INotifyPropertyChanged
{
private int _Thread;
public int Thread
{
get
{
return _Thread;
}
set
{
_Thread = value;
NotifyPropertyChanged("Thread");
}
}
public int RetryCount { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
And a
Telerik.WinControls.Data.ObservableCollection<
RapportoItem
> result = ...
that's bound to the RadGridView using
radGridView1.DataSource= result;
Why when I update the Thread element it's not refreshed in the grid?
Thanks
Paolo
15 Answers, 1 is accepted

Welcome to winforms :p.
Please try using a BindingList<T> and tell me if you see the same behavior.
Hope this helps, if you have any other questions or comments, please let me know,
Best Regards,
Emanuel Varga
Telerik WinForms MVP

It's not updating.... the
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null) //is null here
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
PropertyChanged is null...

Please try this:
using
System;
using
System.ComponentModel;
using
System.Windows.Forms;
using
Telerik.WinControls.UI;
public
partial
class
Form1 : Form
{
private
RadGridView radGridView;
private
BindingList<Person> _list;
private
Timer _updateTimer;
public
Form1()
{
InitializeComponent();
this
.Controls.Add(radGridView =
new
RadGridView());
radGridView.Dock = DockStyle.Fill;
radGridView.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
_list =
new
BindingList<Person>();
for
(
int
i = 0; i < 10; i++)
{
_list.Add(
new
Person(i,
"Person"
+ i));
}
radGridView.DataSource = _list;
}
protected
override
void
OnLoad(EventArgs e)
{
base
.OnLoad(e);
_updateTimer =
new
Timer();
_updateTimer.Interval = 200;
_updateTimer.Tick +=
new
EventHandler(timer_Tick);
_updateTimer.Enabled =
true
;
}
protected
override
void
OnClosing(CancelEventArgs e)
{
base
.OnClosing(e);
if
(_updateTimer !=
null
)
{
_updateTimer.Dispose();
_updateTimer =
null
;
}
}
private
void
timer_Tick(
object
sender, EventArgs e)
{
var personIndex =
new
Random(DateTime.Now.Millisecond).Next(0, _list.Count);
_list[personIndex].Name =
"Person"
+
new
Random(DateTime.Now.Millisecond).Next(0, 10000);
}
}
public
class
Person : INotifyPropertyChanged
{
private
int
_id;
private
string
_name;
public
Person(
int
id,
string
name)
{
Id = id;
Name = name;
}
public
event
PropertyChangedEventHandler PropertyChanged;
public
string
Name
{
get
{
return
_name; }
set
{ _name = value; OnPropertyChanged(
"Name"
); }
}
public
int
Id
{
get
{
return
_id; }
set
{ _id = value; OnPropertyChanged(
"Id"
); }
}
private
void
OnPropertyChanged(
string
propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if
(handler !=
null
) handler(
this
,
new
PropertyChangedEventArgs(propertyName));
}
}
Hope this helps, if you have any other questions or comments, please let me know,
Best Regards,
Emanuel Varga
Telerik WinForms MVP
Like Emanuel said, you have to use a collection which inherits from IBindingList to reflect changes in your data source automatically. One possible solution is to use the BindingList<T> collection. If this does not help, please open a support ticket and send us your application. We will investigate it and we will try to find the best option in your case.
If you have further questions, do not hesitate to ask.
Kind regards,
Jack
the Telerik team
Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

Sorry for opening this rather old post, but I stumbled upon your solution, when finding a way to solve my problem.
My Solution, looks almost the same as your example, but the timer_Tick method gets called by another thread that the gui thread, which then causes an InvalidOperationException when altering the collecion.
How can i change the BindingList<Person> from another thread? Using the Invoker pattern seems not right here, because I'm not specifically updating RadGridView. Moreover I'm updating its datasource.
So
if (radGridView.InvokeRequired)
...
_list.Add(new Person(i, "Person" + i));
does not work here.
How can I solve this problem?
Best regards
Erich
Thank you for writing.
Note that all UI controls are not thread safe controls in the whole Windows Forms platform (not just Telerik controls, but all controls out there). Here is an article on MSDN, describing how to make thread-safe Winforms UI application. This means that any control from the Telerik UI for WinForms suite is not thread safe as well and cannot be used outside the main UI thread. You should use an Invoke to update the controls in cross threading scenario.
If you are still experiencing any further difficulties, feel free to open a support ticket providing a sample project which demonstrates the problem. Thus, we would be able to investigate the precise case and assist you further. Thank you in advance.
I hope this information helps. Should you have further questions I would be glad to help.
Dess
Telerik by Progress

I understand, that I should use Invoke to update my Control from another thread like this:
01.
if
(
this
.textBox1.InvokeRequired)
02.
{
03.
SetTextCallback d =
new
SetTextCallback(SetText);
04.
this
.Invoke(d,
new
object
[] { text });
05.
}
06.
else
07.
{
08.
this
.textBox1.Text = text;
09.
}
But in my case I don't want to update the Control. I'm updating the DataSource of the control.
How can I tell the gui thread to make this update?
Doing it like this:
01.
if
(
this
.listOfItems.InvokeRequired)
02.
{
03.
SetTextCallback d =
new
SetTextCallback(addItem);
04.
this
.Invoke(d,
new
object
[] { listItem});
05.
}
06.
else
07.
{
08.
this
.listOfItems.Add(listItem);
09.
}
seems very wrong. How else can I do it?
I can't believe I'm the only one facing this problem? This seems so trivial, there must be hundreds of solutions out there.
Thank you for writing back.
Following the explained approach in the referred articles, I have prepared a sample code snippet for your reference:
BindingList<Student> collectionOfStudents =
new
BindingList<Student>();
BackgroundWorker bw =
new
BackgroundWorker();
public
Form1()
{
InitializeComponent();
collectionOfStudents.Add(
new
Student(0,
"Peter"
,
"A+"
));
collectionOfStudents.Add(
new
Student(1,
"John"
,
"D-"
));
collectionOfStudents.Add(
new
Student(2,
"Antony"
,
"B+"
));
collectionOfStudents.Add(
new
Student(3,
"David"
,
"A-"
));
collectionOfStudents.Add(
new
Student(4,
"John"
,
"D-"
));
this
.radGridView1.DataSource = collectionOfStudents;
bw.DoWork += bw_DoWork;
}
private
void
bw_DoWork(
object
sender, DoWorkEventArgs e)
{
if
(
this
.radGridView1.InvokeRequired)
{
AddRecordCallback d =
new
AddRecordCallback(AddRecord);
this
.Invoke(d,
new
object
[] { collectionOfStudents });
}
else
{
AddRecord(collectionOfStudents);
}
}
private
void
radButton1_Click(
object
sender, EventArgs e)
{
if
(!bw.IsBusy)
{
bw.RunWorkerAsync();
}
}
delegate
void
AddRecordCallback(BindingList<Student> collection);
private
void
AddRecord(BindingList<Student> collection)
{
for
(
int
i = 0; i < 100; i++)
{
collection.Add(
new
Student(collection.Count ,
"Peter"
,
"A+"
));
}
}
public
class
Student : System.ComponentModel.INotifyPropertyChanged
{
int
m_id;
string
m_name;
string
m_grade;
public
event
PropertyChangedEventHandler PropertyChanged;
public
Student(
int
m_id,
string
m_name,
string
m_grade)
{
this
.m_id = m_id;
this
.m_name = m_name;
this
.m_grade = m_grade;
}
public
int
Id
{
get
{
return
m_id;
}
set
{
if
(
this
.m_id != value)
{
this
.m_id = value;
OnPropertyChanged(
"Id"
);
}
}
}
public
string
Name
{
get
{
return
m_name;
}
set
{
if
(
this
.m_name != value)
{
this
.m_name = value;
OnPropertyChanged(
"Name"
);
}
}
}
public
string
Grade
{
get
{
return
m_grade;
}
set
{
if
(
this
.m_grade != value)
{
this
.m_grade = value;
OnPropertyChanged(
"Grade"
);
}
}
}
protected
virtual
void
OnPropertyChanged(
string
propertyName)
{
if
(PropertyChanged !=
null
)
{
PropertyChanged(
this
,
new
PropertyChangedEventArgs(propertyName));
}
}
}
I hope this information helps. If you have any additional questions, please let me know.
Regards,
Dess
Telerik by Progress

Now I'm facing the next problem.
I have my gridview automatically grouped by two columns. These groups are collapsed by dafault. Now whenerver an item gets removed from my list the group where the item was in, gets expanded automatically, which is very annoying and not what i intended to do.
On the other hand, when I add an item to the ist, this doesn't happen, which how it should be.
How can i turn this off?
Thank you for writing back.
In order to avoid expanding the row when adding/removing a record, it is necessary to set the MasterTemplate.SelectLastAddedRow property to false.
If you are still experiencing any further difficulties, feel free to open a support ticket providing a sample project which demonstrates the problem. Thus, we would be able to investigate the precise case and assist you further. Thank you in advance.
I hope this information helps. If you have any additional questions, please let me know.
Regards,
Dess
Telerik by Progress

In some random cases it still expands some groups, when there is a change in the underlying BindingList.
The next Problem is, that the performace is terrible now. Gui is very slow when i open the view where I see this radgridview. Any Ideas on how i can fix this?
I already take into consideration to use a List instead of a BindingList and then only update when an update-button is pressed. WHat function would allow me to do so?
Thank you for writing back.
Without replicating the issue locally with the group expanding, we can make only conjectures what is causing the problem on your end. That is why we need a sample project demonstrating the issue. This would be the fastest way to make an adequate analysis of the problem and assist you further. Thank you in advance for the cooperation.
As to the performance, if you have a large amount of data (over 200-300K rows), it may affect the performance in RadGridView. For such cases, we can offer our RadVirtualGrid which provides a convenient way to implement your own data management operations and optimizes the performance when interacting with large amounts of data. However, if you don't have a lot of rows and there is a performance problem in your grid, could you please specify the exact steps how to reproduce the performance issue or feel free to submit a support ticket and get back to me with a sample project so I can investigate the precise case? Thank you.
I am looking forward to your reply.
Regards,
Dess
Telerik by Progress

I'm afraid I can't give you a sample application, because my application is too big and with too many interfaces that I can't give it to you.
But if anyone else has a similar problem, this is what I did to have an at least acceptable solution.
I changed the List from a BindingList to a normal List and added a "Refresh" Button.
The command of this button, first sets the source to null and then adds the List as source again.
This way I don't have the performance issues anymore and I don't have the problem of the expanding group.
Furthermore I bind the command to the event of the tab page container where the list is in. So everytime the current tab page gets changed to the view with the list, I run the refresh command.
Thank you for writing back.
I am glad that you have a suitable solution for your case. However, note that unlike the forum, our support ticketing system is a private communication channel and you should not be worried about sharing confidential information. You can be certain that it will be used only for investigation purposes of this case and your privacy will be respected. Confidentiality is also described in our product EULA - See Section 11 of the WinForms EULA and Article V Section 11 of the DevCraft Complete and DevCraft Ultimate EULAs. So, if you decide to provide a project demonstrating the performance problem, we would be glad to investigate it.
If you have any additional questions, please let me know.
Regards,
Dess
Telerik by Progress