I have an existing Asp.NetCore web app built using EFC written in C#. The webpages are built using Razor.
I'm in the process of migrating to using some DevExpress DevExtreme Asp.Net Core controls. Specifically I'm attempting to use the DevExtreme DataGrid to build a Master-Detail data grid. I'm having difficulty setting up the the DataSource for the Detail portion of the grid.
Consider the following class definitions in my model:
public class Address
{
[Key]
public Guid AddressId { get; set; }
public string StreetAddress { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZipCode { get; set; }
public string Country { get; set; }
}
public class Owner
{
[Key]
public Guid OwnerId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public Address OwnerAddress { get; set; }
public string PhoneNumber { get; set; }
public string CellNumber { get; set; }
}
Here is my page definition:
@model IEnumerable<Owner>
@{ Layout = "_DevExtremeLayout"; ViewBag.Title = "All Owners";}
@(Html.DevExtreme().DataGrid<SmartTracPoc.Models.Owner>()
.DataSource(Model)
.RemoteOperations(true)
.AllowColumnReordering(true)
.RowAlternationEnabled(true)
.ShowBorders(true)
.OnContentReady("contentReady")
.Paging(p => p.PageSize(10))
.Pager(p => p
.ShowPageSizeSelector(true)
.AllowedPageSizes(new[] { 10, 25, 50, 100 })
)
.SearchPanel(s => s
.Visible(true)
.HighlightCaseSensitive(true)
)
.GroupPanel(g => g.Visible(true))
.Grouping(g => g.AutoExpandAll(false))
.Columns(columns => {
columns.AddFor(m => m.FirstName);
columns.AddFor(m => m.LastName);
columns.AddFor(m => m.PhoneNumber);
columns.AddFor(m => m.CellNumber);
})
.MasterDetail(md => {
md.Enabled(true);
md.Template(@<text>
<div class="master-detail-caption"><%- data.FullName %> 's Address:</div>
@(Html.DevExtreme().DataGrid<SmartTracPoc.Models.Owner>()
.ColumnAutoWidth(true)
.ShowBorders(true)
.Columns(columns => {
columns.AddFor(m => m.OwnerAddress.StreetAddress);
columns.AddFor(m => m.OwnerAddress.City);
columns.AddFor(m => m.OwnerAddress.State);
columns.AddFor(m => m.OwnerAddress.ZipCode);
columns.AddFor(m => m.OwnerAddress.Country);
})
//.DataSource(Model) ??????? What do I do here?
)
</text>);
})
)
<script>
var collapsed = false;
function contentReady(e) {
if (!collapsed) {
collapsed = true;
e.component.expandRow(["EnviroCare"]);
}
}
function customizeTooltip(pointsInfo) {
return { text: parseInt(pointsInfo.originalValue) + "%" };
}
</script>
This builds and runs successfully. The issue is that no data is displayed for the fields referenced from the Address class. In the above implementation, both the Master and Detail portions of the grid should be using the same DataSource (in this case "Model" -> IEnumerable).
How do I achieve this?
Your model in the master detail isn't Owner
it's Address
please try the following:
.MasterDetail(md => {
md.Enabled(true);
md.Template(@<text>
<div class="master-detail-caption"><%- data.FullName %> 's Address:</div>
@(Html.DevExtreme().DataGrid<SmartTracPoc.Models.Address>()
.ColumnAutoWidth(true)
.ShowBorders(true)
.Columns(columns => {
columns.AddFor(m => m.StreetAddress);
columns.AddFor(m => m.City);
columns.AddFor(m => m.State);
columns.AddFor(m => m.ZipCode);
columns.AddFor(m => m.Country);
})
.DataSource(new JS("data.address"));
)
</text>);
})
This is why I don't recomend using the MVC controll, using JQuery is much easier to controll the component.
Secondly all operations should be server-side. If you want the detail of an Owner
then have an API action for that porpuse, then have the master detail call that action.