RowSourceNeeded and Sort

10 posts, 1 answers
  1. Hunter
    Hunter avatar
    44 posts
    Member since:
    Aug 2012

    Posted 30 Apr 2012 Link to this post

    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.
  2. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 01 May 2012 Link to this post

    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
  3. UI for WinForms is Visual Studio 2017 Ready
  4. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 01 May 2012 Link to this post

    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
  5. Hunter
    Hunter avatar
    44 posts
    Member since:
    Aug 2012

    Posted 01 May 2012 Link to this post

    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!
  6. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 02 May 2012 Link to this post

    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
  7. Answer
    Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 02 May 2012 Link to this post

    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
  8. Hunter
    Hunter avatar
    44 posts
    Member since:
    Aug 2012

    Posted 02 May 2012 Link to this post

    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!
  9. Richard Slade
    Richard Slade avatar
    3000 posts
    Member since:
    May 2009

    Posted 03 May 2012 Link to this post

    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
  10. ALVARO
    ALVARO avatar
    1 posts
    Member since:
    Nov 2013

    Posted 06 Nov 2013 Link to this post

    sorry but then, 

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

    thanks a lot.

    Alvaro Aguilar

  11. George
    Admin
    George avatar
    500 posts

    Posted 11 Nov 2013 Link to this post

    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 >>
Back to Top
UI for WinForms is Visual Studio 2017 Ready