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

GridView children values update issue

5 Answers 145 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Dilshod
Top achievements
Rank 1
Dilshod asked on 30 Mar 2011, 05:36 PM
Hi,

I have two level object related hierarchy grid.
Child object field depends on Parent object field.
When changing a value in parent object it does not update children rows.
But it updates parent row itself. We can see it on C field which depends on that value too.

Here is the code:
public partial class RadForm1 : Telerik.WinControls.UI.RadForm
    {
        List<A> glist;
        public RadForm1()
        {
            InitializeComponent();
            glist = new List<A>();
 
            A objA = new A();
            objA.B = 10;
            objA.L.Add(new B("asdf1"));
            objA.L.Add(new B("asdf2"));
            objA.L.Add(new B("asdf3"));
            objA.L.Add(new B("asdf4"));
 
            A objB = new A();
            objB.B = 20;
            objB.L.Add(new B("f1"));
            objB.L.Add(new B("f2"));
            objB.L.Add(new B("f3"));
            objB.L.Add(new B("F4"));
 
            glist.Add(objA);
            glist.Add(objB);
 
            gv.DataSource = glist;
            gv.AutoGenerateHierarchy = true;
            gv.Columns["L"].IsVisible = false;             
        }
 
        class A
        {
            List<B> list;
            int b;
            int c;
            public A()
            {
                list = new List<B>();
            }
            public List<B> L
            {
                get { return this.list; }
                set { this.list = value; }
            }
            public int B
            {
                get {return this.b;}
                set
                {
                    this.b = value;
                    this.c = value * 5;
                    foreach (B bb in L)
                        bb.a = value;
                }
            }
            public int C
            {
                get { return this.c; }
            }
        }
        class B
        {
            int _a;
            string _b;
            public B()
            { }
            public B(string stringparam)
            {               
                b = stringparam;
            }
            public int a
            {
                get { return this._a; }
                set { this._a = value; }
            }
            public string b
            {
                get { return this._b; }
                set { this._b = value; }
            }
        }
}

5 Answers, 1 is accepted

Sort by
0
Emanuel Varga
Top achievements
Rank 1
answered on 31 Mar 2011, 08:23 AM
Hello Dilshod,

I believe this is a bug in with the AutoGenerateHierarchy, at first i thought that it is related to the fact that you were using normal lists, but I've adapted your example with both bindinglists + INotifyPropertyChanged + Invalidate all child rows on parent row changed. Although if you take a look on the row's data bound item you will see that the values have been updated, these changes are not applied in the cells.

This are the changes I've made to your example:
using System.ComponentModel;
using System.Windows.Forms;
using Telerik.WinControls.UI;
 
public partial class Form1 : Telerik.WinControls.UI.RadForm
{
    BindingList<ClassA> glist;
    private RadGridView gv = new RadGridView();
    public Form1()
    {
        InitializeComponent();
        this.Controls.Add(gv);
        gv.Dock = DockStyle.Fill;
        gv.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
 
        glist = new BindingList<ClassA>();
 
        ClassA objA = new ClassA();
        objA.Num1 = 10;
        objA.List.Add(new ClassB("asdf1"));
        objA.List.Add(new ClassB("asdf2"));
        objA.List.Add(new ClassB("asdf3"));
        objA.List.Add(new ClassB("asdf4"));
 
        ClassA objB = new ClassA();
        objB.Num1 = 20;
        objB.List.Add(new ClassB("f1"));
        objB.List.Add(new ClassB("f2"));
        objB.List.Add(new ClassB("f3"));
        objB.List.Add(new ClassB("F4"));
 
        glist.Add(objA);
        glist.Add(objB);
        gv.CellValueChanged += new GridViewCellEventHandler(gv_CellValueChanged);
        gv.DataBindingComplete += new GridViewBindingCompleteEventHandler(gv_DataBindingComplete);
        gv.DataSource = glist;
        gv.AutoGenerateHierarchy = true;
    }
 
    void gv_CellValueChanged(object sender, GridViewCellEventArgs e)
    {
        if (!(e.Row.Parent is GridDataRowElement))
        {
            e.Row.InvalidateRow();
            foreach (var row in e.Row.ChildRows)
            {
                row.InvalidateRow();
            }
        }
    }
 
    void gv_DataBindingComplete(object sender, GridViewBindingCompleteEventArgs e)
    {
        gv.Columns["List"].IsVisible = false;
    }
 
    public class ClassA : INotifyPropertyChanged
    {
        BindingList<ClassB> list;
        int num1;
        int num2;
        public ClassA()
        {
            list = new BindingList<ClassB>();
        }
        public BindingList<ClassB> List
        {
            get
            {
                return this.list;
            }
            set
            {
                this.list = value;
                OnPropertyChanged("List");
            }
        }
        public int Num1
        {
            get
            {
                return this.num1;
            }
            set
            {
                this.num1 = value;
                this.num2 = value * 5;
                foreach (ClassB bb in List)
                    bb.Num3 = value;
                OnPropertyChanged("Num1");
            }
        }
        public int Num2
        {
            get
            {
                return this.num2;
            }
        }
 
        #region INotifyPropertyChanged Members
 
        public event PropertyChangedEventHandler PropertyChanged;
 
        #endregion
 
        private void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
 
    public class ClassB : INotifyPropertyChanged
    {
        int num3;
        string name;
        public ClassB()
        {
        }
        public ClassB(string stringparam)
        {
            Str = stringparam;
        }
        public int Num3
        {
            get
            {
                return this.num3;
            }
            set
            {
                this.num3 = value;
                OnPropertyChanged("Num3");
            }
        }
        public string Str
        {
            get
            {
                return this.name;
            }
            set
            {
                this.name = value;
                OnPropertyChanged("Str");
            }
        }
 
        #region INotifyPropertyChanged Members
 
        public event PropertyChangedEventHandler PropertyChanged;
 
        #endregion
 
        private void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}

I would suggest opening a bug report on this issue.

Hope this helps, if you have any other questions or comments, please let me know,

Best Regards,
Emanuel Varga

Telerik WinForms MVP
0
Dilshod
Top achievements
Rank 1
answered on 31 Mar 2011, 10:28 AM
Hello again,

Yes I meant that objects are update but not cells too.
So should I public this on Public Issue Tracking System or where?

0
Richard Slade
Top achievements
Rank 2
answered on 31 Mar 2011, 11:14 AM
Hello,

Emanuel is referring to the support tickets section. If you go to Your Account, and submit a support ticket you will find this section. Or you can click on this link to see your available support lists

hope that helps
Richard
0
Dilshod
Top achievements
Rank 1
answered on 31 Mar 2011, 07:49 PM
Hello Emanuel,
if it does not work with AutoGenerateHierarchy mode
could you help with convert this sample to manual hierarchy bind ?
Is it the only way that this is be done by using GridViewRelation?
If yes then I really don't know what should to set on ParentColumnNames and ChildColumnNames properties.

0
Accepted
Julian Benkov
Telerik team
answered on 05 Apr 2011, 12:15 PM
Hello Dilshod,

In object-relational hierarchy mode RadGridView does not observe changes in the inner IList/IBindingList properties and can not refresh itself automatically after a change in some of the related parent values.
The reason for the luck of this functionality regards performance and memory consumption concerns
which arise if we should handle all changes in every inner IBindingList implementation. In this scenario you should manually refresh the inner GridViewTemplate using the following solution:

void radGridView1_CellValueChanged(object sender, Telerik.WinControls.UI.GridViewCellEventArgs e)
{
    GridViewHierarchyRowInfo hierarchyRow = e.Row as GridViewHierarchyRowInfo;
    hierarchyRow.ActiveView.ViewTemplate.Refresh();
}

I hope this helps.

All the best,
Julian Benkov
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Tags
GridView
Asked by
Dilshod
Top achievements
Rank 1
Answers by
Emanuel Varga
Top achievements
Rank 1
Dilshod
Top achievements
Rank 1
Richard Slade
Top achievements
Rank 2
Julian Benkov
Telerik team
Share this question
or