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

RowSourceNeeded and Sort

9 Answers 205 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Hunter
Top achievements
Rank 1
Hunter asked on 30 Apr 2012, 04:25 PM
Hello,
I have a hierarchal grid view which uses the RowSourceNeeded event to fill the master template's child template when a row is expanded (works like a champ). The child template contains its own child template which is also filled during this event. My question is, why does a column sort fire the RowSourceNeeded event? If this is by design is there a way to defeat this functionality as it requires the two child templates to be re-filled unnecessarily (for each expanded row in my grid - ouch)? Thanks.

9 Answers, 1 is accepted

Sort by
0
Richard Slade
Top achievements
Rank 2
answered on 01 May 2012, 11:15 AM
Hello Hunter, 

If I understand you correctly, then the RowSourceNeeded event isn't fired when clicking on the column headers (for sorting). 
Have you had a look at the load on demand documentation

If I have misunderstood, then please could you post a small sample that demonstrates the issue using the format code block, and I'll be happy to take a look for you. 
Thanks
Richard
0
Richard Slade
Top achievements
Rank 2
answered on 01 May 2012, 12:37 PM
Hello Hunter, 

After preparing a quick sample, I see what you mean now. That the event fires when sorting the child template. As far as I know, this is by design. The sample below shows when the event fires. 

Designer File
namespace RadControlsWinFormsApp1
{
    partial class RadForm1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;
 
        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
 
        #region Windows Form Designer generated code
 
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.radLabel1 = new Telerik.WinControls.UI.RadLabel();
            this.radGridView1 = new Telerik.WinControls.UI.RadGridView();
            ((System.ComponentModel.ISupportInitialize)(this.radLabel1)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.radGridView1)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this)).BeginInit();
            this.SuspendLayout();
            //
            // radLabel1
            //
            this.radLabel1.Location = new System.Drawing.Point(12, 12);
            this.radLabel1.Name = "radLabel1";
            this.radLabel1.Size = new System.Drawing.Size(56, 18);
            this.radLabel1.TabIndex = 3;
            this.radLabel1.Text = "Selected...";
            //
            // radGridView1
            //
            this.radGridView1.Location = new System.Drawing.Point(12, 36);
            this.radGridView1.Name = "radGridView1";
            this.radGridView1.Size = new System.Drawing.Size(319, 335);
            this.radGridView1.TabIndex = 4;
            this.radGridView1.Text = "radGridView1";
            //
            // RadForm1
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(343, 383);
            this.Controls.Add(this.radGridView1);
            this.Controls.Add(this.radLabel1);
            this.Name = "RadForm1";
            //
            //
            //
            this.RootElement.ApplyShapeToControl = true;
            this.Text = "RadForm1";
            this.ThemeName = "ControlDefault";
            ((System.ComponentModel.ISupportInitialize)(this.radLabel1)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.radGridView1)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();
 
        }
 
        #endregion
 
        private Telerik.WinControls.UI.RadLabel radLabel1;
        private Telerik.WinControls.UI.RadGridView radGridView1;
    }
}

Form 1
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Telerik.WinControls;
using Telerik.WinControls.UI;
using Telerik.WinControls.Primitives;
using System.Linq;
 
namespace RadControlsWinFormsApp1
{
    public partial class RadForm1 : Telerik.WinControls.UI.RadForm
    {
 
        public List<Job> _jobs = new List<Job>();
 
        public RadForm1()
        {
            InitializeComponent();
 
            int i = 0;
            while (i <= 20)
            {
                _jobs.Add(new Job(i, "Job " + i.ToString()));
                i++;
            }
 
            List<User> users = new List<User>();
            int k = 0;
            while (k <= 20)
            {
                users.Add(new User(k, "User " + k.ToString(), k));
                k++;
            }
 
 
 
            this.radGridView1.DataSource = users;
 
            GridViewTemplate childTemplate = CreateChildTemplate();
            this.radGridView1.Templates.Add(childTemplate);
 
            childTemplate.HierarchyDataProvider = new GridViewEventDataProvider(childTemplate);
            this.radGridView1.RowSourceNeeded += new GridViewRowSourceNeededEventHandler(radGridView1_RowSourceNeeded);
      
        }
 
        private GridViewTemplate CreateChildTemplate()
        {
            GridViewTemplate template = new GridViewTemplate();
            template.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
 
            GridViewDecimalColumn idColumn = new GridViewDecimalColumn("Id");
            GridViewTextBoxColumn namecolumn = new GridViewTextBoxColumn("Name");
            template.Columns.AddRange(idColumn, namecolumn);
 
            return template;
        }
 
        void radGridView1_RowSourceNeeded(object sender, GridViewRowSourceNeededEventArgs e)
        {
            this.radLabel1.Text = "Row Source Needed " + DateTime.Now.ToLongTimeString();
 
            User rowView = e.ParentRow.DataBoundItem as User;
 
            var jobs = from j in _jobs
                       where j.Id == rowView.JobId
                       select j;
 
            foreach (Job job in jobs)
            {
                GridViewRowInfo row = e.Template.Rows.NewRow();
                row.Cells["Id"].Value = job.Id;
                row.Cells["Name"].Value = job.Name;
 
                e.SourceCollection.Add(row);
            }
        }
 
    }
 
    public class User
    {
        public User(int id, string name, int jobId)
        {
            Id = id;
            Name = name;
            JobId = jobId;
        }
 
        public User()
        { }
 
        public int Id
        {
            get;
            set;
        }
 
        public string Name
        {
            get;
            set;
        }
 
        public int JobId
        {
            get;
            set;
        }
 
    }
 
    public class Job
    {
        public Job(int id, string name)
        {
            Id = id;
            Name = name;
        }
 
        public Job()
        { }
 
        public int Id
        {
            get;
            set;
        }
 
        public string Name
        {
            get;
            set;
        }
    }
}

Hope that helps
Richard
0
Hunter
Top achievements
Rank 1
answered on 01 May 2012, 06:30 PM
Thank you for taking a look at this for me. You are correct, the issue I am having is that the RowSourceNeeded event fires when the child template is sorted. What I want to do is sort the child template without the RowSourceNeeded event firing. I was caught off guard because I can reorder columns, expand/collapse templates, etc. without the event firing so it seemed odd that it was firing in this scenario. Is there a way to cancel this event (i.e. keep it from clearing the template's rows)?

If I can't stop the event from removing the template's rows then I'll check the pro's and con's of storing the data locally (ex. XML file). When the RowSourceNeeded event fires I would check this local file first. If the file doesn't have the requested data then I would go out to the database, write the data to the local file, and finally fill the grid. Any thoughts? Thanks again!
0
Richard Slade
Top achievements
Rank 2
answered on 02 May 2012, 10:35 AM
Hi Hunter, 

Yes, the RowSourceNeeded event will fire and is needed when the child template is sorted. 
You can, of course disable sorting if you need to just for the child template. 
this.radGridView1.MasterTemplate.Templates[0].EnableSorting = false;

Other than this, I am not sure what else I could suggest. When using the RadGridView with this Load on Deamand mode, will require this event on sorting. 

Hope this helps
Richard
0
Accepted
Richard Slade
Top achievements
Rank 2
answered on 02 May 2012, 11:46 AM
Hi Again Hunter, 

Try this as an idea to get around your issue. 

1: Declare the following members
public IList<GridViewRowInfo> _rows;
public bool _sorting;

2: Add these event handlers
this.radGridView1.SortChanging += new GridViewCollectionChangingEventHandler(radGridView1_SortChanging);
this.radGridView1.SortChanged += new GridViewCollectionChangedEventHandler(radGridView1_SortChanged);

3: Set the _sorting property when the child grid is being sorted
void radGridView1_SortChanging(object sender, GridViewCollectionChangingEventArgs e)
{
    if (sender.GetType() == typeof(GridViewTemplate))
    {
        _sorting = true;
    }
}
 
void radGridView1_SortChanged(object sender, GridViewCollectionChangedEventArgs e)
{
    if (sender.GetType() == typeof(GridViewTemplate))
    {
        _sorting = false;
    }
}

4: Set the e.SourceCollection to be the rows if you are sorting. Otherwise, do the normal and set the _rows to be the e.SourceCollection
void radGridView1_RowSourceNeeded(object sender, GridViewRowSourceNeededEventArgs e)
{
 
    if (_sorting)
    {
        foreach (GridViewRowInfo row in _rows)
        {
            e.SourceCollection.Add(row);
        }
        return;
    }
    this.radLabel1.Text = "Row Source Needed " + DateTime.Now.ToString("hh:mm:ss.ff");
 
 
    User rowView = e.ParentRow.DataBoundItem as User;
 
    var jobs = from j in _jobs
               where j.Id == rowView.JobId
               select j;
 
    foreach (Job job in jobs)
    {
        GridViewRowInfo row = e.Template.Rows.NewRow();
        row.Cells["Id"].Value = job.Id;
        row.Cells["Name"].Value = job.Name;
 
        e.SourceCollection.Add(row);
    }
    _rows = e.SourceCollection;
}

Let me know if that helps
Richard
0
Hunter
Top achievements
Rank 1
answered on 02 May 2012, 05:30 PM
Thank you for all the support Richard! I went ahead and marked your latest reply as the answer to my question as it demonstrated the sorting catch that I needed to move forward (Big Help!). Just an FYI, this example will configure every previously opened child template with the same source. In other words, "_rows" is filled with the last un-sort request handled by the RowSourceNeeded event. When a user sorts a column, all previously opened child templates are filled with the same rows. I'm sure that this was done purely to get me an example, unless I've totally missed something ;). I'll weigh the benefits of keeping the rows in memory vs writing them to disk. Once again, thank you for your support!
0
Richard Slade
Top achievements
Rank 2
answered on 03 May 2012, 09:23 AM
Hi Hunter, 

Yes, you're right. That was a careless mistake. My apologies. Perhaps though this has given you some ideas on how to move forward. You'd probably need to store the whole child table in memory. If you need any further help though, please let me know. 
Thanks
Richard
0
ALVARO
Top achievements
Rank 1
answered on 07 Nov 2013, 01:01 AM
sorry but then, 

when sorting GridViewTemplate, after load data in radGridView1_RowSourceNeeded, but data no ordering. why??
is possible??

thanks a lot.

Alvaro Aguilar

0
George
Telerik team
answered on 11 Nov 2013, 02:22 PM
Hi Alvaro,

Thank you for writing.

Can you please explain in a little more details what exactly is your problem since the information you provided me with so far is not enough for me to determine what is your case and what is the cause of the issue. Also, some sample code may be of great help in the process of investigation.

Looking forward to your reply.

Regards,
George
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WINFORMS.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
Tags
GridView
Asked by
Hunter
Top achievements
Rank 1
Answers by
Richard Slade
Top achievements
Rank 2
Hunter
Top achievements
Rank 1
ALVARO
Top achievements
Rank 1
George
Telerik team
Share this question
or