This is a migrated thread and some comments may be shown as answers.

Updating row when changing property

15 Answers 388 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Michele
Top achievements
Rank 2
Michele asked on 30 Sep 2011, 11:21 AM
Hello,
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

Sort by
0
Emanuel Varga
Top achievements
Rank 1
answered on 30 Sep 2011, 11:39 AM
Hello Paolo,

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
0
Michele
Top achievements
Rank 2
answered on 30 Sep 2011, 11:43 AM
Hello Emanuel,
It's not updating.... the

private void NotifyPropertyChanged(String info)
      {
          if (PropertyChanged != null) //is null here
          {
              PropertyChanged(this, new PropertyChangedEventArgs(info));
          }
      }

PropertyChanged is null...
0
Emanuel Varga
Top achievements
Rank 1
answered on 30 Sep 2011, 12:17 PM
Hello Paolo,

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
0
Jack
Telerik team
answered on 04 Oct 2011, 12:00 PM
Hello Paolo,

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 >>

0
Erich
Top achievements
Rank 1
answered on 06 Jul 2016, 02:40 PM

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

0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 07 Jul 2016, 09:50 AM
Hello 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.

Regards,
Dess
Telerik by Progress
Check out the Windows Forms project converter, which aids the conversion process from standard Windows Forms applications written in C# or VB to Telerik UI for WinForms.For more information check out this blog post and share your thoughts.
0
Erich
Top achievements
Rank 1
answered on 07 Jul 2016, 12:26 PM

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.

0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 07 Jul 2016, 01:06 PM
Hello Erich,

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
Check out the Windows Forms project converter, which aids the conversion process from standard Windows Forms applications written in C# or VB to Telerik UI for WinForms.For more information check out this blog post and share your thoughts.
0
Erich
Top achievements
Rank 1
answered on 08 Jul 2016, 06:33 AM

I managed to solve the problem like this

thank you!

0
Erich
Top achievements
Rank 1
answered on 08 Jul 2016, 06:54 AM

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?

0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 08 Jul 2016, 10:58 AM
Hello Erich,

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
Check out the Windows Forms project converter, which aids the conversion process from standard Windows Forms applications written in C# or VB to Telerik UI for WinForms.For more information check out this blog post and share your thoughts.
0
Erich
Top achievements
Rank 1
answered on 29 Jul 2016, 08:12 AM

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?

0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 29 Jul 2016, 11:55 AM
Hello Erich,

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
Check out the Windows Forms project converter, which aids the conversion process from standard Windows Forms applications written in C# or VB to Telerik UI for WinForms.For more information check out this blog post and share your thoughts.
0
Erich
Top achievements
Rank 1
answered on 02 Aug 2016, 08:29 AM

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.

 

 

 

0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 02 Aug 2016, 11:24 AM
Hello Erich,

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
Check out the Windows Forms project converter, which aids the conversion process from standard Windows Forms applications written in C# or VB to Telerik UI for WinForms.For more information check out this blog post and share your thoughts.
Tags
GridView
Asked by
Michele
Top achievements
Rank 2
Answers by
Emanuel Varga
Top achievements
Rank 1
Michele
Top achievements
Rank 2
Jack
Telerik team
Erich
Top achievements
Rank 1
Dess | Tech Support Engineer, Principal
Telerik team
Share this question
or