I'm attempting to utilise a generic Grid component, like this:
@typeparam T <div class="gridWrapper"> @if (loaded) { <SfGrid DataSource="@(DataSource)" Toolbar="@(ToolBar)" AllowFiltering="true" AllowPaging="true" AllowSelection="true" AllowSorting="true" Width="100%" AllowPdfExport="true" AllowExcelExport="true" AllowTextWrap="true" AllowGrouping="true"> @if (GridCommandModel.GetIcons().Any()) { <GridEvents TValue="T" CommandClicked="@(OnCommandClicked)"></GridEvents> } <GridEvents OnToolbarClick="@(OnToolbarClicked)" TValue="T"></GridEvents> @if (GridSortColumns.Any()) { <GridSortSettings> <GridSortColumns> @foreach (var column in GridSortColumns) { <GridSortColumn Field="@(column.GetField())" Direction="@(column.GetDirection())"></GridSortColumn> } </GridSortColumns> </GridSortSettings> } <GridColumns> @foreach (var column in GridColumns) { @if (column.GetWidth() > 0) { <GridColumn Field="@(column.GetField())" HeaderText="@(column.GetHeaderText())" Width="@($"{column.GetWidth().ToString()}px")"></GridColumn> } else { <GridColumn Field="@(column.GetField())" HeaderText="@(column.GetHeaderText())"></GridColumn> } } @if (GridCommandModel.GetIcons().Any()) { @if (GridCommandModel.GetWidth() > 0) { <GridColumn TextAlign="Syncfusion.Blazor.Grids.TextAlign.Center" Field="@(GridCommandModel.GetHeaderText())" Width="@($"{GridCommandModel.GetWidth()}px")"> <GridCommandColumns> @foreach (var icon in GridCommandModel.GetIcons()) { <GridCommandColumn ButtonOption="@(new CommandButtonOptions() {IconCss = icon})"></GridCommandColumn> } </GridCommandColumns> </GridColumn> } else { <GridColumn TextAlign="Syncfusion.Blazor.Grids.TextAlign.Center" Field="@(GridCommandModel.GetHeaderText())"> <GridCommandColumns> @foreach (var icon in GridCommandModel.GetIcons()) { <GridCommandColumn ButtonOption="@(new CommandButtonOptions() {IconCss = icon})"></GridCommandColumn> } </GridCommandColumns> </GridColumn> } } </GridColumns> </SfGrid> } </div> @code { [Parameter] public IEnumerable<T> DataSource { get; set; } [Parameter] public List<GridColumnModel> GridColumns { get; set; } [Parameter] public List<GridSortColumnModel> GridSortColumns { get; set; } [Parameter] public List<string> ToolBar { get; set; } [Parameter] public GridCommandModel GridCommandModel { get; set; } [Parameter] public EventCallback<ClickEventArgs> OnToolbarClicked { get; set; } [Parameter] public EventCallback<CommandClickEventArgs<T>> OnCommandClicked { get; set; } private bool loaded = false; protected override async Task OnParametersSetAsync() { loaded = true; StateHasChanged(); } }
Where the column model is like so:
using TextAlign = Syncfusion.Blazor.Grids.TextAlign; namespace FIS2withSyncfusion.Models { public class GridColumnModel { private string Field; private string HeaderText; private TextAlign TextAlign = TextAlign.Center; private int? Width; private bool WidthSet = false; public GridColumnModel(string field, string headerText) { Field = field; HeaderText = headerText; } public GridColumnModel(string field, string headerText, int width) { Field = field; HeaderText = headerText; Width = width; WidthSet = true; } public string GetField() { return Field; } public string GetHeaderText() { return HeaderText; } public TextAlign GetTextAlign() { return TextAlign; } public int GetWidth() { return WidthSet ? Width.Value : 0; } public void SetTextAlign(TextAlign textAlign) { TextAlign = textAlign; } } }
The Sort Column model is as follows:
using SortDirection = Syncfusion.Blazor.Grids.SortDirection; namespace FIS2withSyncfusion.Models { public class GridSortColumnModel { private bool Ascending; private string Field; public GridSortColumnModel(string field, bool ascending = true) { Field = field; Ascending = ascending; } public SortDirection GetDirection() { return Ascending ? SortDirection.Ascending : SortDirection.Descending; } public string GetField() { return Field; } } }
And the command model is:
using System.Collections.Generic; namespace FIS2withSyncfusion.Models { public class GridCommandModel { private string HeaderText; private List<string> Icons; private int? Width; public GridCommandModel(string headerText) { HeaderText = headerText; Icons = new List<string>(); } public GridCommandModel(string headerText, int width) { HeaderText = headerText; Width = width; Icons = new List<string>(); } public void AddIcon(string icon) { Icons.Add(icon); } public string GetHeaderText() { return HeaderText; } public List<string> GetIcons() { return Icons; } public int GetWidth() { return Width ?? 0; } } }
A limited example of a use case for it would be:
@using FIS2withSyncfusion.Shared.Email @using System.Diagnostics.Eventing.Reader @using Microsoft.EntityFrameworkCore @using TextAlign = Syncfusion.Blazor.Grids.TextAlign @inject IDbContextFactory<FIS2_DbContext> _contextFactory; @inject SessionState _state; @inject IEmailService _emailService; @if (loaded) { <div class="dashWrapper"> <SfDashboardLayout AllowDragging="false" AllowFloating="false" AllowResizing="false" CellAspectRatio="2.5" CellSpacing="@(new double[]{20,20})" Columns="3"> <DashboardLayoutPanels> <DashboardLayoutPanel Column="0" Row="0" SizeX="2" SizeY="2" Id="notesGrid"> <HeaderTemplate> <h3>Notes</h3> </HeaderTemplate> <ContentTemplate> <FIS2withSyncfusion.Controls.Grid T="@(GetAllStudentNotesResult)" DataSource="@(notes)" ToolBar="@(new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel", "PdfExport", "ExcelExport" })" GridColumns="@(GridColumns)" GridCommandModel="@(CommandModel)" GridSortColumns="@(GridSortColumns)" OnToolbarClicked="@(OnGridToolbarClicked)" OnCommandClicked="@(OnGridCommandClicked)"></FIS2withSyncfusion.Controls.Grid> </ContentTemplate> </DashboardLayoutPanel> </DashboardLayoutPanels> </SfDashboardLayout> </div> } @code { [Parameter] public string StudentId { get; set; } private bool loaded = false; private List<GridColumnModel> GridColumns = new(); private List<GridSortColumnModel> GridSortColumns = new(); private GridCommandModel CommandModel; private List<GetAllStudentNotesResult> notes; private List<string> GridToolbar = new List<string>() { "Add", "Edit", "Delete", "Update", "Cancel", "PdfExport", "ExcelExport" }; protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { GetGridColumns(); GetGridSortColumns(); GetGridCommandModel(); await GetAllStudentNotes(); loaded = true; StateHasChanged(); } } private void GetGridColumns() { GridColumns = new List<GridColumnModel>(); GridColumns.Add(new GridColumnModel(nameof(GetAllStudentNotesResult.CreatedDate), "Created")); GridColumns.Add(new GridColumnModel(nameof(GetAllStudentNotesResult.CreatedBy), "Created By")); GridColumns.Add(new GridColumnModel(nameof(GetAllStudentNotesResult.NoteType_Desc), "Note Type")); GridColumns.Add(new GridColumnModel(nameof(GetAllStudentNotesResult.NoteSubType_Desc), "Note Sub Type")); GridColumns.Add(new GridColumnModel(nameof(GetAllStudentNotesResult.NoteDetails), "Note")); } private void GetGridSortColumns() { GridSortColumns = new List<GridSortColumnModel>(); GridSortColumns.Add(new GridSortColumnModel(nameof(GetAllStudentNotesResult.CreatedDate), false)); } private void GetGridCommandModel() { CommandModel = new GridCommandModel("Commands", 150); CommandModel.AddIcon("fa fa-trash-can"); } private async Task GetAllStudentNotes() { var context = _contextFactory.CreateDbContext(); var procedures = context.Procedures; notes = await procedures.GetAllStudentNotesAsync(StudentId); } private async Task OnGridToolbarClicked(ClickEventArgs args) { } private async Task OnGridCommandClicked(CommandClickEventArgs<GetAllStudentNotesResult> args) { } }
Unfortunately, at some point while rendering the component, it receives a NullReferenceException. I've stepped through the code several times and can't find where the exception is coming from. Is there any kind of pointer you can give me?
|
@if (GridCommandModel.GetIcons().Any())
{
@if (GridCommandModel.GetWidth() > 0)
{
<GridColumn TextAlign="Syncfusion.Blazor.Grids.TextAlign.Center" HeaderText="@(GridCommandModel.GetHeaderText())" Width="@($"{GridCommandModel.GetWidth()}px")">
<GridCommandColumns>
@foreach (var icon in GridCommandModel.GetIcons())
{
<GridCommandColumn ButtonOption="@(new CommandButtonOptions() {IconCss = icon})"></GridCommandColumn>
}
</GridCommandColumns>
</GridColumn>
}
else
{
<GridColumn TextAlign="Syncfusion.Blazor.Grids.TextAlign.Center" HeaderText="@(GridCommandModel.GetHeaderText())">
<GridCommandColumns>
@foreach (var icon in GridCommandModel.GetIcons())
{
<GridCommandColumn ButtonOption="@(new CommandButtonOptions() {IconCss = icon})"></GridCommandColumn>
}
</GridCommandColumns>
</GridColumn>
}
}
|
|
[Grid.Razor]
[Index.razor]
|