Databinding update not changing in GridView

5 posts, 1 answers
  1. Chris Kirkman
    Chris Kirkman avatar
    101 posts
    Member since:
    Apr 2010

    Posted 22 Jan 2018 Link to this post

    I've successfully bound data to the grid; however, when the model bound to the grid changes the results don't show up in the grid until I give focus to that row.  For the purposes of this issue, don't worry about the meaning of the "scans" and "_snc" objects as they have nothing to do with the issue.

     

    Here is where I successfully bind to a model called "ComparisonScansViewModel" which has a public "List<ComparisonScanViewModel> Scans" property.

     

                await Task.Factory.StartNew(() =>
                {
                    // source scans for comparison
                    _model = new ComparisonScansViewModel(_snc, scans);
                });
                BatchComparisonGrid.DataSource = _model.Scans;

     

    Here is the model code (loads up fine)

     

        public class ComparisonScansViewModel
        {
            public ComparisonScansViewModel(SNC snc, List<Scan> scans)
            {
                Scans = new List<ComparisonScanViewModel>();
                scans.ForEach(s =>
                {
                    Scans.Add(new ComparisonScanViewModel()
                    {
                        Id = s.ScanId,
                        Type = snc.Values.GetInstance(s.Type).Text,
                        Field = s.FieldSize.ToString(),
                        Energy = s.EnergyForDisplay,
                        Depth = s.Depth,
                    });
                });
            }
            public List<ComparisonScanViewModel> Scans;
        }
        public class ComparisonScanViewModel
        {
            public int Id { get; set; }
            public string Type { get; set; }
            public string Field { get; set; }
            public string Energy { get; set; }
            public decimal? Depth { get; set; }
            public decimal Gamma { get; set; }
        }

     

    In the code below I am hard coding the value of a property in my model named "Gamma".  When the grid is first shown this value is '0' and when the value changes in a dropdownlist I am going to properly update the "Gamma" value; however, for the purposes of debugging I am simply hard coding for now.

     

            private async void ReferenceProjectDropDownList_SelectedValueChanged(object sender, EventArgs e)
            {
                if (null != _model)
                {
                    BatchComparisonWaitingBar.Visibility = Telerik.WinControls.ElementVisibility.Visible;
                    BatchComparisonWaitingBar.StartWaiting();
                    BatchComparisonStatusLabel.Text = "Calculating gamma...";

                    // calculate the passing % (gamma) for each item in the table
                    await Task.Factory.StartNew(() =>
                    {
                        for (int i = 0; i < _model.Scans.Count; i++)
                        {
                            //Thread.Sleep(500);
                            ComparisonScanViewModel sm = _model.Scans[i];
                            sm.Gamma =250m;
                        }
                    });

                    BatchComparisonWaitingBar.Visibility = Telerik.WinControls.ElementVisibility.Collapsed;
                    BatchComparisonWaitingBar.StopWaiting();
                    BatchComparisonStatusLabel.Text = "Ready";
                }
            }

     

    When this event above is fired, the values in the model ARE updated; however, the results of this update are NOT reflected in the UI.  I have to scroll through the grid view and/or click on a row to see the value change in the grid.

  2. Chris Kirkman
    Chris Kirkman avatar
    101 posts
    Member since:
    Apr 2010

    Posted 22 Jan 2018 in reply to Chris Kirkman Link to this post

    I implemented INotifyPropertyChanged on the model; however, it still doesn't work.  ;(

    public class ComparisonScanViewModel : INotifyPropertyChanged
    {
        decimal _gamma = 0m;
     
        public int Id { get; set; }
        public string Type { get; set; }
        public string Field { get; set; }
        public string Energy { get; set; }
        public decimal? Depth { get; set; }
        public decimal Gamma
        {
            get { return _gamma; }
            set { _gamma = value; OnPropertyChanged("Gamma"); }
        }
     
        public event PropertyChangedEventHandler PropertyChanged;
        void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
  3. Chris Kirkman
    Chris Kirkman avatar
    101 posts
    Member since:
    Apr 2010

    Posted 22 Jan 2018 in reply to Chris Kirkman Link to this post

    Still not working but wanted to show.  Went with a more aggressive option, created a base class that implements INotifyPropertyChanged (I do this in my WPF applications).  Then had the model class derive from the base class.

     

    public class ViewModelBase : INotifyPropertyChanged
    {
        public ViewModelBase() { }
     
        #region Property changed interface
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    }
     
    public class ComparisonScansViewModel : ViewModelBase
    {
        public ComparisonScansViewModel(SNC snc, List<Scan> scans)
        {
            _scans = new ObservableCollection<ComparisonScanViewModel>();
     
            scans.ForEach(s =>
            {
                Scans.Add(new ComparisonScanViewModel()
                {
                    Id = s.ScanId,
                    Type = snc.Values.GetInstance(s.Type).Text,
                    Field = s.FieldSize.ToString(),
                    Energy = s.EnergyForDisplay,
                    Depth = s.Depth,
                    Gamma = 0m
                });
            });
        }
     
        ObservableCollection<ComparisonScanViewModel> _scans;
        public ObservableCollection<ComparisonScanViewModel> Scans { get { return _scans; } set { _scans = value; } }
    }
     
    public class ComparisonScanViewModel : ViewModelBase
    {
        decimal _gamma = 0m;
     
        public int Id { get; set; }
        public string Type { get; set; }
        public string Field { get; set; }
        public string Energy { get; set; }
        public decimal? Depth { get; set; }
        public decimal Gamma
        {
            get { return _gamma; }
            set { _gamma = value; OnPropertyChanged("Gamma"); }
        }
    }
  4. Answer
    Dess | Tech Support Engineer, Sr.
    Admin
    Dess | Tech Support Engineer, Sr.  avatar
    3273 posts

    Posted 23 Jan 2018 Link to this post

    Hello, Chris,

    Thank you for writing.  

    RadGridView is capable of fetching bindable properties and data. However, one important issue must be noted: during the data binding process, the grid extracts the data from the data source, but for any later changes in the data source, RadGridView should be notified. Your bindable collection and business objects should follow some standards established in .NET in order to notify RadGridView about the changes:
    - The collection that you will bind to RadGridView should implement IBindingList or IBindingListView interfaces. This will allow RadGridView to get notified about insert and delete operations of records.
    - Your business objects should implement INotifyPropertyChanged interface (.NET 2.0). This will allow RadGridView to reflect changes which occur to the properties of the business objects

    Additional information is available in the following help article: https://docs.telerik.com/devtools/winforms/gridview/populating-with-data/reflecting-custom-object-changes-in-rgv

    If you are still experiencing any further difficulties, it would be greatly appreciated if you can provide a sample project demonstrating the undesired behavior. 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
    Progress Telerik
    Try our brand new, jQuery-free Angular components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
  5. Chris Kirkman
    Chris Kirkman avatar
    101 posts
    Member since:
    Apr 2010

    Posted 23 Jan 2018 in reply to Dess | Tech Support Engineer, Sr. Link to this post

    Dess, thanks again!  Using "BindingList<myobect>" worked whereas using "ObservableCollection<myobject>" did not.  It's nice to see items update right before my eyes one after the other as the values are calculated.
Back to Top