Bound DatagridView not refreshing

I have a DataGridView bound to an array of objects.  When I change values in the objects the DatagridView does not show the change.  I have to do a .refresh.  Also the event CellValueChanged does not get triggered when values are changed by the program to the object values (they are exposed as public properties).

Thanks for any help,

Luis C. Uribe



Answer this question

Bound DatagridView not refreshing

  • krskumar

    Scott,

    I tried your idea but still it does not work.  I implemented in my class INotifyPropertyChanged and then I raise the event when the property is changed.

    I found a BindingList property that seems key on all this called raiseItemChangedEvents and it needs to be true for the list to send notifications.  The property appears in the documentation but when I try to set it it does not exist for the BindingList.  Perhaps you may have some more information on this.

    Thanks,

    Luis


  • orygreg

    Are you using a BindingSource()

    Try this first: 

    private List<UnitType> _stl_UnitTypes = new List<UnitType>();
    BindingSource unitTypeBindingSource = new BindingSource();
    unitTypeBindingSource.DataSource = _stl_UnitTypes;
    clmUnitType.DataSource = unitTypeBindingSource;


    That took care of a lot of my problems with datasource changing and grid not updating.

    If this doesn't help, let me know, I'm fighting some issues with the DataGridView being bound to object collection as well.


  • Irishmanco

    From what I can gather the BindingList raises the ListChanged event but I don't see how will it raise events for the grid.  Someone could explain the process, how this happens via the BindingSource

    Luis


  • lawlordds

    Thanks Scott for you help and your clear example.  My grid is now working after raising the event for the different properties.

    Luis

  • colwelltim

    raiseItemChangedEvents is a private bool that should be true when your object implements INotifyPropertyChanged.  You can verify this by checking
       (yourList as IRaiseItemChangedEvents).RaisesItemChangedEvents

    I'm not sure where things are going wrong for you.  Give the code below a whirl and see whether it works for you.  It has a BindingList of MyObjects, which each have an int property and a string property.  Clicking the form adds "." to the string, so you can click and see the string change in the DataGridView.  Then we can play "is it your build, is it your code, or is there a bug somewhere".
       -Scott

    using System;

    using System.Collections.Generic;

    using System.ComponentModel;

    using System.Data;

    using System.Drawing;

    using System.Text;

    using System.Windows.Forms;

    namespace WindowsApplication2

    {

    public class Form1 : Form

    {

    public Form1()

    {

    DataGridView dgv = new DataGridView();

    BindingSource source = new BindingSource();

    BindingList<MyObject> list = new BindingList<MyObject>();

    for (int i = 0; i < 5; i++)

    {

    list.Add(new MyObject(i, "Val" + i));

    }

    source.DataSource = list;

    dgv.DataSource = source;

    Controls.Add(dgv);

    dgv.Top = 30;

    dgv.Size = new Size(200, 200);

    Click += delegate { list[0].StringValue += "."; };

    }

    [STAThread]

    static void Main()

    {

    Application.EnableVisualStyles();

    Application.SetCompatibleTextRenderingDefault(false);

    Application.Run(new Form1());

    }

    }

    class MyObject : INotifyPropertyChanged

    {

    public MyObject()

    {

    }

    public MyObject(int i, string str)

    {

    IntValue = i;

    StringValue = str;

    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)

    {

    if (null != PropertyChanged)

    {

    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

    }

    }

    int intValue;

    public int IntValue

    {

    get { return intValue; }

    set

    {

    intValue = value;

    OnPropertyChanged("IntValue");

    }

    }

    string stringValue;

    public string StringValue

    {

    get { return stringValue; }

    set

    {

    stringValue = value;

    OnPropertyChanged("StringValue");

    }

    }

    }

    }


  • smerilatt

    Ryan,

    I tried the BindingSource and unfortunately it did not work.

    Thanks,

    Luis


  • Youngermandl

    A couple more things to try: use BindingList<> instead of List<> -- BindingList<> builds in property change notification.

    I'm unclear on this:
       "When I change values in the objects the DatagridView does not show the change"

    Does that mean you're replacing the entire object, or only changing a property of the object   If it's a property, the object should implement INotifyPropertyChanged, firing "I changed the 'LastName' value" when you change a property.
       Scott

  • jo0ls

    The DataGridView listens for changes on the list.  BindingList raises these events when you delete an item, add an item, or change an item (like setting the 5th value in the list to a new instance of your class).  What it can't do by itself is tell you when you've changed one property on the list (say that you set the 5th item's Name property).  If the class implements INotifyPropertyChanged, the BindingList will pick this up as well (when you implement this interface, you raise an event every time you change a property, saying "I just changed the 'Name' property").

    BindingSource shouldn't really be necessary for this scenario, but it helps in a number of other scenarios, like binding to a non-IList IEnumerable, making parent-child binding easier, making binding the same data on other forms easier, etc.  For simplicity, I find that it's easier to use BindingSource all the time.
       -Scott
       


  • Hamp Turner

    I am not using a List, I am using an array of objects as:

    Private VSymb(1000) As CSymb

    CSymb has public properties and that is what changes. 
    Do you mean I should use a BindingList instead

    Thanks,

    Luis



  • Bound DatagridView not refreshing