[]
        
(Showing Draft Content)

Render Cells Using a Custom Column

Custom columns provide programmatic control over cell rendering and direct access to the underlying row data through row.DataItem.

This approach is suitable for reusable rendering logic, event-driven interactions, and advanced rendering scenarios.

Step 1: Create a Custom Column Class

Extend GridColumn and override the cell rendering behavior.

public class CustomColumn : GridColumn
{
    [Parameter]
    public Action<object> OnEditClicked { get; set; }

    protected override RenderFragment GetCellContentRenderFragment(
        GridCellType cellType,
        GridRow row)
    {
        if (cellType == GridCellType.Cell)
        {
            return new RenderFragment(builder =>
            {
                builder.OpenElement(0, "button");

                builder.AddAttribute(
                    1,
                    "onclick",
                    EventCallback.Factory.Create<MouseEventArgs>(
                        this,
                        e => OnEditClicked?.Invoke(row.DataItem)));

                builder.AddContent(2, "Info");

                builder.CloseElement();
            });
        }

        return base.GetCellContentRenderFragment(cellType, row);
    }
}


Step 2: Add the Custom Column to the Grid

<FlexGrid ItemsSource="customers"
          AutoGenerateColumns="false">
    <FlexGridColumns>
        <GridColumn Binding="FirstName" />
        <GridColumn Binding="LastName" />

        <CustomColumn OnEditClicked="ShowEditPopup" />
    </FlexGridColumns>
</FlexGrid>


Note: Accessing data through SelectedItem or SelectedIndex is supported, but it depends on the current grid selection state and is not recommended for reusable rendering scenarios.


Step 3: Handle the Click Event

Access the row data directly through row.DataItem.

@code {
    void ShowEditPopup(object dataItem)
    {
        var customer = dataItem as Customer;

        // Process customer data
    }
}


Complete Code Example

Custom Column Class

public class CustomColumn : GridColumn
{
    [Parameter]
    public Action<object> OnEditClicked { get; set; }

    protected override RenderFragment GetCellContentRenderFragment(
        GridCellType cellType,
        GridRow row)
    {
        if (cellType == GridCellType.Cell)
        {
            return new RenderFragment(builder =>
            {
                builder.OpenElement(0, "button");

                builder.AddAttribute(1, "class", "btn btn-sm btn-primary");

                builder.AddAttribute(
                    2,
                    "onclick",
                    EventCallback.Factory.Create<MouseEventArgs>(
                        this,
                        e => OnEditClicked?.Invoke(row.DataItem)));

                builder.AddContent(3, "Info");

                builder.CloseElement();
            });
        }

        return base.GetCellContentRenderFragment(cellType, row);
    }
}

Usage in the Page

<FlexGrid ItemsSource="customers"
          IsReadOnly="true"
          AutoGenerateColumns="false">
    <FlexGridColumns>
        <GridColumn Binding="FirstName" Header="First Name" />
        <GridColumn Binding="LastName" Header="Last Name" />

        <CustomColumn OnEditClicked="ShowEditPopup" />
    </FlexGridColumns>
</FlexGrid>

@code {
    List<string> info = new();

    void ShowEditPopup(object dataItem)
    {
        var customer = dataItem as Customer;

        info.Add($"Customer: {customer.FirstName} {customer.LastName}");
    }
}

After completing these steps, FlexGrid displays standard data columns together with a custom button column generated through a GridColumn override.

Each button is associated directly with its corresponding row data through row.DataItem. When the button is clicked, the related Customer object is passed to the event handler.


Add Loading Indicators and Popup Windows

Custom columns can be combined with loading indicators and popup windows to support asynchronous workflows and provide visual feedback during processing operations.

Add a Loading Indicator

Step 1: Reuse the Custom Column

Reuse the existing CustomColumn implementation to maintain consistent row-level interaction behavior.

Step 2: Add a Loading Indicator Container

Wrap the FlexGrid inside a container that supports overlay rendering.

<div style="position:relative;">

    <FlexGrid ItemsSource="customers"
              AutoGenerateColumns="false">
        <FlexGridColumns>
            <GridColumn Binding="FirstName" />
            <GridColumn Binding="LastName" />

            <CustomColumn
                OnEditClicked="((d) => ShowEditPopup((Customer)d))" />
        </FlexGridColumns>
    </FlexGrid>

    @if (IsLoading)
    {
        <div style="
            position:absolute;
            left:50%;
            top:50%;
            transform:translate(-50%, -50%);
            background-color:#5252DF;
            border-radius:20px;
            padding:12px;">

            <p style="font-size:26px; color:white;">
                Loading...
            </p>
        </div>
    }
</div>


Step 3: Implement Loading State Logic

Introduce an IsLoading flag to control the loading overlay.

@code {
    bool IsLoading;

    async Task ShowEditPopup(Customer data)
    {
        IsLoading = true;

        StateHasChanged();

        await Task.Delay(3000);

        // Process customer data

        IsLoading = false;
    }
}

After the operation completes, the loading overlay is removed and normal grid interaction resumes.

Note: The loading overlay temporarily covers the grid interface while processing is in progress. This behavior prevents additional user interaction during the operation.


Display Row Data in a Popup Window

C1Window can be used together with custom columns to display row-specific data or asynchronous processing results.

Step 1: Add the Popup Window

<FlexGrid ItemsSource="customers"
          AutoGenerateColumns="false">
    <FlexGridColumns>
        <CustomColumn
            OnEditClicked="((d) => ShowEditPopup((Customer)d))" />
    </FlexGridColumns>
</FlexGrid>

<C1Window @ref="window">
    <PopupHeader>Data</PopupHeader>

    <PopupContent>
        Loading...
    </PopupContent>
</C1Window>

Step 2: Implement Asynchronous Processing

@code {
    C1Window window;

    async Task ShowEditPopup(Customer data)
    {
        window.Open();

        await Task.Delay(3000);

        // Process data

        window.Close();
    }
}

Complete Code Example

<FlexGrid ItemsSource="customers"
          AutoGenerateColumns="false">
    <FlexGridColumns>
        <CustomColumn
            OnEditClicked="((d) => ShowEditPopup((Customer)d))" />
    </FlexGridColumns>
</FlexGrid>

<C1Window @ref="window">
    <PopupHeader>Data</PopupHeader>

    <PopupContent>
        Loading...
    </PopupContent>
</C1Window>

@code {
    C1Window window;

    async Task ShowEditPopup(Customer data)
    {
        window.Open();

        await Task.Delay(3000);

        // Process data

        window.Close();
    }
}

After completing these steps, FlexGrid supports asynchronous row-level interaction through popup windows and loading indicators.

When a row action button is clicked, the application opens a popup window or displays a loading overlay while the operation is processed asynchronously.

As a result, the interface provides responsive user feedback during long-running operations without blocking the application workflow.