RowSourceNeeded Problem

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

    Posted 25 Jan 2018 Link to this post

    I have a RowSourceNeeded event, and inside that event I create my child GridView and add rows to it.  There are conditions that would keep me from adding the child GridView; however, I still need to add this child when I do have the data required to do so.

    In this event I check a property "model.Parameters" which could be null; however, it is not always going to be null (after handling the RowSourceNeeded event) and when not null I need to add the child GridView.

    Here's where I add it.

    // get the analysis parameter differences for this row (scan)
    private async void BatchComparisonGrid_RowSourceNeeded(object sender, GridViewRowSourceNeededEventArgs e)
    {
        // tell user we're getting the analysis parameters
        UpdateWaitingBar(ElementVisibility.Visible, "Getting analysis parameters");
     
        // get item bound to the row
        ComparisonScanViewModel model = e.ParentRow.DataBoundItem as ComparisonScanViewModel;
     
        await Task.Factory.StartNew(() =>
        {
            if (null != model && null != model.Parameters)
            {
                // I don't do anything here, I just needed to cause 'model.Parameters' to
                // be called since it is a timely call.
            }
        });
     
        // update the UI
        if (null != model &&
            null != model.Parameters)
        {
            foreach (ComparisonAnalysisParameterViewModel am in model.Parameters)
            {
                // build values to go in the row details grid
                GridViewRowInfo row = e.Template.Rows.NewRow();
                row.Cells["Description"].Value = am.Title;
                row.Cells["Value"].Value = am.Value;
     
                e.SourceCollection.Add(row);
            }
     
            e.ParentRow.IsExpanded = true;
        }
     
        // tell the user we're done
        UpdateWaitingBar(ElementVisibility.Collapsed);
    }

     

    Later, I'm listening to the CurrentRowChanging event.  Here I can get the same data from the model and potentially build the child GridView; however, I don't have the necessary information required that was provided to me in the RowSourceNeeded event.  I.e. e.Template and e.SourceCollection.

     

    // row is changing in the grid and time to expand that item to show the details for the row
    private void BatchComparisonGrid_CurrentRowChanging(object sender, CurrentRowChangingEventArgs e)
    {
        if (e.NewRow is GridViewHierarchyRowInfo)
        {
            foreach (var item in BatchComparisonGrid.Rows)
            {
                item.IsExpanded = false;
            }
     
            // get model
            ComparisonScanViewModel model = e.NewRow.DataBoundItem as ComparisonScanViewModel;
            if(null != model.Parameters)
            {
                // code would go here that checks to see if this row already had the child GridView
                // added, and if not AND model.Parameters is not null, then we'll add the child GridView now.
     
                // BUT, how to do this from here ????
            }
     
            // expand
            e.NewRow.IsExpanded = true;
        }
    }

     

    Is there some way to access what I need from the CurrentRowChanging event in order to add the child GridView...since the RowSourceNeeded event is never raised again after the first time it is raised?

     

     

  2. Answer
    Dess | Tech Support Engineer, Sr.
    Admin
    Dess | Tech Support Engineer, Sr.  avatar
    3201 posts

    Posted 26 Jan 2018 Link to this post

    Hello, Chris,

    Thank you for writing.  

    When you use the load on demand hierarchy approach in RadGridView, the first time you try expanding a parent node, the RowSourceNeeded event is called. In the event handler you fill the data for the respective template and parent row. This data is cached and the next time you expand the same parent RadGridView uses the cached data. In the CurrentRowChanging event you have access to the new current row from where you can get the template by the CurrentRowChangingEventArgs.NewRow.ViewTemplate property. However, you don't have access to the SourceCollection. It is relevant for the GridViewRowSourceNeededEventArgs. You can store in an external data structure the necessary information from the SourceCollection when the RowSourceNeeded event is fired and use it later when the CurrentRowChanging event is fired. Alternatively, you can extract this information directly from your data source. Feel free to use this approach which suits your requirement best.

    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.
  3. Chris Kirkman
    Chris Kirkman avatar
    101 posts
    Member since:
    Apr 2010

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

    I tried something similar to what you suggested yesterday and was getting an exception saying that I couldn't access a disposed object.  However, this must have been talking about the GridViewRowSourceNeededEventArgs.  Instead today I decided to only cache the GridViewTemplate and the SourceCollection from those event args for when I do have what I need to fill it in.  I added the following code to be able to handle caching what I need to do this.

    List<RowSource> _sources = new List<RowSource>();
    class RowSource
    {
        public int Id { get; set; }
        public GridViewTemplate Template { get; set; }
        public IList<GridViewRowInfo> SourceCollection
        {
            get; set;
        }
    }
    void AddChild(RowSource source, ComparisonScanViewModel model)
    {
        foreach (ComparisonAnalysisParameterViewModel am in model.Parameters)
        {
            // build values to go in the row details grid
            GridViewRowInfo row = source.Template.Rows.NewRow();
            row.Cells["Description"].Value = am.Title;
            row.Cells["Value"].Value = am.Value;
     
            source.SourceCollection.Add(row);
        }
     
        //source.ParentRow.IsExpanded = true;
    }

     

    Now, I changed the RowSourceNeeded to include the following...

    else
    {
        // cache until I can actually load with model data
        _sources.Add(new RowSource()
        {
            Id = model.Id,
            Template = e.Template,
            SourceCollection = e.SourceCollection,
        });
    }

     

    Then, I changed the CurrentRowChanging to check to see if I have what I need to place the data in to the SourceCollection as shown below.

    // get model
    ComparisonScanViewModel model = e.NewRow.DataBoundItem as ComparisonScanViewModel;
    if (null != model.Parameters)
    {
        // was the row source not able to be set before because the parameters
        // were not available at the time?  check again now and if it IS
        // available we have the ability to add the child gridview now.
        RowSource source = _sources.Find(s => s.Id == model.Id);
        if (null != source)
        {
            AddChild(source, model);
            _sources.Remove(source);
        }
    }

     

    It appears to be working now, so that's good.  Thanks.

  4. Dess | Tech Support Engineer, Sr.
    Admin
    Dess | Tech Support Engineer, Sr.  avatar
    3201 posts

    Posted 29 Jan 2018 Link to this post

    Hello, Chris,  

    Thank you for writing back. 

    I am glad that the provided information was useful for handling your scenario. The provided code snippet seems OK. Hence, if it behavse the way you need, feel free to use it.

    I hope this information helps. If you have any additional questions, please let me know. 

     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.
Back to Top