Grids in master/slave configuration, slave data always one click behind.

I've set up grids in master/slave configuration, using the master's RowSelected event to change the data for the slave.  I'm using a generic custom dataadapter.  When I first run the program, the master and slave are in sync.  But when I click on the next row of the master, nothing changes in the slave.  Then when I click on another row in the master, the slave changes to display the data of the prior selection in the master. In other words, the slave is always one click behind.  How do I fix this?

Here's my code:
Areas.razor:
@page "/Lists/Areas"

<h1>Areas</h1>

@if (areaList == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <div class="col-lg-12 control-section">
        <div class="content-wrapper">
            <div class="row">
                <div class='e-mastertext'><b>Areas</b></div>
                <SfGrid TValue="Area" SelectedRowIndex=0 Toolbar="@(new List<Object>() { "Add", "Edit", "Delete" })" >
                    <GridEditSettings AllowAdding="true" AllowDeleting="true" AllowEditing="true" Mode="EditMode.Dialog"></GridEditSettings>                    
                    <SfDataManager Adaptor="Adaptors.CustomAdaptor">
                        <CustomDataAdaptor T="Area" Details="areaList"></CustomDataAdaptor>
                    </SfDataManager>
                    <GridEvents RowSelected="AreaRowSelecthandler" TValue="Area" ></GridEvents>
                    <GridColumns>
                        <GridColumn Field=@nameof(Area.Name) HeaderText="Name" Width="110"> </GridColumn>
                        <GridColumn Field=@nameof(Area.Levy) HeaderText="Levy" Width="110"></GridColumn>
                    </GridColumns>
                </SfGrid>
                <div class='e-statustext'>Showing Rates for Area: <b>@SelectedArea</b></div>
                <SfGrid @ref="areaRateGrid" TValue="AreaRate" SelectedRowIndex=0 Toolbar="@(new List<Object>() { "Add", "Edit", "Delete" })" >
                    <GridEditSettings AllowAdding="true" AllowDeleting="true" AllowEditing="true" Mode="EditMode.Dialog"></GridEditSettings>                    
                    <SfDataManager Adaptor="Adaptors.CustomAdaptor">
                        <CustomDataAdaptor T="AreaRate" Details="areaRateList"></CustomDataAdaptor>
                    </SfDataManager>
                    <GridColumns>
                        <GridColumn Field="PumpParameter.Name" HeaderText="Pump Type" Width="110"> </GridColumn>
                        <GridColumn Field="RateOccasion.Name" HeaderText="Rate Occasion" Width="110"> </GridColumn>
                        <GridColumn Field=@nameof(AreaRate.BaseRate) HeaderText="Base Rate" Width="110"></GridColumn>
                    </GridColumns>
                </SfGrid>
            </div>
        </div>
    </div>
    <style>
        .e-statustext,
        .e-mastertext {
            font-size: 15px;
            font-family: Roboto;
            opacity: 0.87;
            padding: 1em;
        }
    </style>
}

@code {
    SfGrid<AreaRate> areaRateGrid;
    List<Area> areaList;
    List<AreaRate> areaRateList;
    List<PumpParameter> pumpParameters;
    public string SelectedArea { get; set; }
    public Guid? RowIndex { get; set; }

    protected override async Task OnInitializedAsync()
    {
        await Task.Run(() =>
        {
            areaList = context.Areas.Where(n => n.IsActive == true).ToList<Area>();
            areaList.Sort();
            areaRateList = context.AreaRates.Where(n => n.AreaId == areaList.First<Area>().Id).ToList<AreaRate>();
            areaRateList.Sort();
            pumpParameters = context.PumpParameters.ToList<PumpParameter>();
        });
    }
    public void AreaRowSelecthandler(RowSelectEventArgs<Area> Args)
    {
        SelectedArea = Args.Data.Name;
        areaRateList = Args.Data.AreaRates;
        areaRateList.Sort();
        areaRateGrid.Refresh();
    }
}

CustomDataAdaptor.razor:
@using Newtonsoft.Json
@inject IJSRuntime jsRuntime

@typeparam T

@inherits DataAdaptor<T>

<CascadingValue Value="@this">
    @ChildContent
</CascadingValue>

@code {
    [Parameter]
    public RenderFragment ChildContent { get; set; }
    [Parameter]
    public List<T> Details { get; set; }

    // Performs data Read operation
    public override object Read(DataManagerRequest dm, string key = null)
    {
        IEnumerable<T> DataSource = (IEnumerable<T>)Details;
        aif (dm.Skip != 0)
        {
            //Paging
            DataSource = DataOperations.PerformSkip(DataSource, dm.Skip);
        }
        if (dm.Take != 0)
        {
            DataSource = DataOperations.PerformTake(DataSource, dm.Take);
        }
        if (dm.Search != null && dm.Search.Count > 0)
        {
            // Searching
            DataSource = DataOperations.PerformSearching(DataSource, dm.Search);
        }
        if (dm.Sorted != null && dm.Sorted.Count > 0)
        {
            // Sorting
            DataSource = DataOperations.PerformSorting(DataSource, dm.Sorted);
        }
        if (dm.Where != null && dm.Where.Count > 0)
        {
            // Filtering
            DataSource = DataOperations.PerformFiltering(DataSource, dm.Where, dm.Where[0].Operator);
        }
        int count = Details.Cast<T>().Count();  // return entire record count
        return dm.RequiresCounts ? new DataResult() { Result = DataSource, Count = count } : (object)DataSource;
    }
    // Performs Update operation
    public override object Update(DataManager dm, object value, string keyField, string key)
    {
        return value;
    }
}



3 Replies 1 reply marked as answer

VN Vignesh Natarajan Syncfusion Team March 30, 2021 05:51 AM UTC

Hi Mike,  
 
Thanks for contacting Syncfusion support.  
 
Query: “ But when I click on the next row of the master, nothing changes in the slave. In other words, the slave is always one click behind.  
 
We have analyzed the reported query and we understand that you are facing trouble in updating the slave / detail Grid datasource in Master Grid’s RowSelected event. We are able to reproduce the reported issue at our end also. We found that you have refreshed the Grid component after changing the CustomAdaptor component Details Parameter.  
 
But we would like to you that we have rendered the CustomAdaptor as Child component to SfGrid component. So it will be refreshed after refreshing the Grid component. hence the records are updated in one step behind.  So we suggest you achieve your requirement by sending the selected record details using Query property of the Grid.  
 
In the provided code example, we found that you have filtered the slave Grid record using Id value in parent grid record. So we suggest you to use Where query to filter the records. Refer the below code example.  
 
<div class="col-lg-12 control-section"> 
    <div class="content-wrapper"> 
        <div class="row"> 
            <div class='e-mastertext'><b>Areas</b></div> 
            <SfGrid TValue="Area" SelectedRowIndex=Toolbar="@(new List<Object>() { "Add""Edit""Delete" })"> 
                <GridEditSettings AllowAdding="true" AllowDeleting="true" AllowEditing="true" Mode="EditMode.Dialog"></GridEditSettings> 
                <SfDataManager Adaptor="Adaptors.CustomAdaptor"> 
                    <CAComp T="Area" Details="areaList"></CAComp> 
                </SfDataManager> 
                <GridEvents RowSelected="AreaRowSelecthandler" TValue="Area"></GridEvents> 
                <GridColumns> 
                    <GridColumn Field=@nameof(Area.AreaID) HeaderText="Name" Width="110"> </GridColumn> 
                    <GridColumn Field=@nameof(Area.CustomerID) HeaderText="Levy" Width="110"></GridColumn> 
                </GridColumns> 
            </SfGrid> 
            <div class='e-statustext'>Showing Rates for Area: <b>@SelectedArea</b></div> 
            <SfGrid @ref="areaRateGrid" TValue="AreaRate" Query="@Qry" SelectedRowIndex=Toolbar="@(new List<Object>() { "Add""Edit""Delete" })"> 
                <GridEditSettings AllowAdding="true" AllowDeleting="true" AllowEditing="true" Mode="EditMode.Dialog"></GridEditSettings> 
                <SfDataManager Adaptor="Adaptors.CustomAdaptor"> 
                    <CAComp T="AreaRate" Details="areaRateList"></CAComp> 
                </SfDataManager> 
                <GridColumns> 
                    <GridColumn Field="@nameof(AreaRate.AreaID)" HeaderText="Pump Type" Width="110"> </GridColumn> 
                    <GridColumn Field="@nameof(AreaRate.CustomerID)" HeaderText="Rate Occasion" Width="110"> </GridColumn> 
                    <GridColumn Field=@nameof(AreaRate.BaseRate) HeaderText="Base Rate" Width="110"></GridColumn> 
                </GridColumns> 
            </SfGrid> 
        </div> 
    </div> 
</div> 
<style> 
    .e-statustext, 
    .e-mastertext { 
        font-size15px; 
        font-familyRoboto; 
        opacity0.87; 
        padding1em; 
    } 
</style> 
  
@code{ 
    public Query Qry { getset; } = new Query(); 
    SfGrid<AreaRate> areaRateGrid; 
    public List<Area> areaList; 
    public List<AreaRate> areaRate; 
    public List<AreaRate> areaRateList; 
    public string SelectedArea { getset; } 
    public Guid? RowIndex { getset; } 
  
  
  
    public void AreaRowSelecthandler(RowSelectEventArgs<Area> Args) 
    { 
        Qry = new Query().Where(new WhereFilter() { Field = "CustomerID", Operator = "equal", value = Args.Data.CustomerID }); 
    } 
    protected override void OnInitialized() 
    { 
        areaList = Enumerable.Range(1, 5).Select(x => new Area() 
        { 
            AreaID = 1000 + x, 
            CustomerID = (new string[] { "ALFKI""ANANTR""ANTON""BLONP""BOLID" })[x - 1], 
            Freight = 2.1 * x, 
        }).ToList(); 
  
        areaRateList = Enumerable.Range(1, 75).Select(x => new AreaRate() 
        { 
            AreaID = 1000 + x, 
            CustomerID = (new string[] { "ALFKI""ANANTR""ANTON""BLONP""BOLID" })[new Random().Next(5)], 
            BaseRate = 2.1 * x, 
        }).ToList(); 
    } 
 
 
In above code example, we have filter the CustomerID column with value selected from RowSelected Event. Similarly we suggest you to Filter the corresponding column in slave grid based on the Master Grid Id value.  
 
Kindly download the sample which we have prepared using above solution from below  
 
 
Please get back to us if you have further queries or if you are facing difficulties in achieving your requirement.  
 
Regards, 
Vignesh Natarajan  
 


Marked as answer

MI Mike March 30, 2021 07:23 AM UTC

Wow, thanks a ton.  I was working on this problem for, well, I won't admit how long.  This solution perfectly solved my problem :)


VN Vignesh Natarajan Syncfusion Team March 30, 2021 11:17 AM UTC

Hi Mike,  

Thanks for the update.  

We are glad to hear that you have resolved your query using our solution.  

Please get back to us if you have further queries.  

Regards, 
Vignesh Natarajan 


Loader.
Up arrow icon