簡體   English   中英

Blazor 服務器應用程序如何實現具有多個編輯的主從 Blazor 頁面

[英]Blazor Server App How to implement master-detail Blazor page with multiple edits

我正在開發一個 Blazor 服務器應用程序項目。 我想實現一個具有多個內聯編輯的主從 blazor 頁面,類似於下面的示例?

主細節樣本

我檢查了一些像 MudBlazor 這樣免費提供的開源第三方組件,但不幸的是,沒有主細節組件。 最接近的組件是具有內聯編輯模式的 MudTable。 泥表樣本

感謝您的幫助,在此先感謝。

編輯

Radzen 用主細節層次結構做我想要的:)

<RadzenDataGrid EditMode="DataGridEditMode.Multiple">

編輯2

這是我的訂單和訂單詳細信息實體和相關代碼。

public class Order
    {
        public int Id { get; set; }
        
        [Required]
        public DateTime OrderDateTime { get; set; }
        [Required]
        [MaxLength(250)]
        public string CustomerName { get; set; }
        [Required]
        [MaxLength(250)]
        public string VendorName { get; set; }
        public string Status { get; set; }
        [MaxLength(50)]
        public string DoneBy { get; set; }
        public List<OrderDetail> OrderDetails { get; set; }


    }

public class OrderDetail
    {
        public int Id { get; set; }
        
        [Required]
        [MaxLength(100)]
        public string ProductCode { get; set; }
        [Required]
        [MaxLength(250)]
        public string ProductName { get; set; }
        [Required]
        public int BuyQuantity { get; set; }
        [Required]
        public int SellQuantity { get; set; }
        public double CostRatio { get; set; }
        public double UnitCost { get; set; }
        public double TotalBuyPrice { get; set; }
        public double TotalSellPrice { get; set; }
        [MaxLength(150)]
        public string ShippingNumber { get; set; }
        public string Status { get; set; }
        [MaxLength(150)]
        public string TrackingNumber { get; set; }
        [MaxLength(400)]
        public string Description { get; set; }
        public int OrderId { get; set; }
        public virtual Order Order { get; set; }
    }
public interface IOrderRepository
{
    Task AddOrderAsync(Order Order);
    Task<Order?> GetOrderByIdAsync(int id);
    Task<IEnumerable<Order>> GetOrderByCustomerName(string name);
    Task<IEnumerable<Order>> GetOrderByVendorName(string name);
    Task UpdateOrderAsync(Order order);
}
public class OrderRepository : IOrderRepository
    {
        private readonly IMSContext _db;
        
        public OrderRepository(IMSContext db)
        {
            this._db = db;
           
        }

        public async Task AddOrderAsync(Order order)
        {
            
            if (_db.Orders.Any(x =>
                    x.Id == order.Id)) return;

            this._db.Orders.Add(order);

            await this._db.SaveChangesAsync();
        }
        public async Task<Order?> GetOrderByIdAsync(int id)
        {
            return await this._db.Orders.FindAsync(id);
        }
        public async Task<IEnumerable<Order>> GetOrderByCustomerName(string name)
        {
            return await this._db.Orders.Where(x => x.CustomerName.ToLower().IndexOf(name.ToLower()) >= 0).ToListAsync();
        }
        public async Task<IEnumerable<Order>> GetOrderByVendorName(string name)
        {
            return await this._db.Orders.Where(x => x.VendorName.ToLower().IndexOf(name.ToLower()) >= 0).ToListAsync();
        }
        public async Task UpdateOrderAsync(Order order)
        {
            if (_db.Orders.Any(x =>
                    x.Id != order.Id)) return;

            var ord = await this._db.Orders.FindAsync(order.Id);
            if (ord != null)
            {
                ord.CustomerName = order.CustomerName;
                ord.VendorName = order.VendorName;
                ord.Status = order.Status;
                ord.OrderDateTime = order.OrderDateTime;
                ord.OrderDetails = order.OrderDetails;
               
                await _db.SaveChangesAsync();
            }
        }
    }
 public class EditOrderUseCase: IEditOrderUseCase
    {
        private readonly IOrderRepository _orderRepository;

        public EditOrderUseCase(IOrderRepository orderRepository)
        {
            this._orderRepository = orderRepository;
        }

        public async Task ExecuteAsync(Order order)
        {
            await _orderRepository.UpdateOrderAsync(order);
        }
    }
public class AddOrderUseCase : IAddOrderUseCase
    {
        private readonly IOrderRepository _orderRepository;

        public AddOrderUseCase(IOrderRepository orderRepository)
        {
            this._orderRepository = orderRepository;
        }
        public async Task ExecuteAsync(Order order)
        {
            await _orderRepository.AddOrderAsync(order);
        }
    }

這是我正在嘗試實現的主從 Blazor 頁面。 我想我在實現主從頁面時有點迷失了。 當用戶單擊“添加新訂單”按鈕時,我想添加新訂單和訂單詳細信息。 用戶只能編輯訂單或訂單詳細信息(可以編輯多行的詳細信息)或兩者兼而有之。 你能指導我完成這項工作嗎?

這是 Blazor 頁面:

@page "/orders"
@using IMS.CoreBusiness
@using IMS.UseCases.Interfaces.Order


@inject NavigationManager NavigationManager
@inject IViewOrdersByCustomerNameUseCase ViewOrdersByCustomerNameUseCase
@inject IAddOrderUseCase AddOrderUseCase
@inject IEditOrderUseCase EditOrderUseCase

<h1>Orders</h1>
<RadzenButton Icon="add_circle_outline" style="margin-bottom: 10px" Text="Add New Order" Click="@InsertRow" Disabled=@(orderToInsert != null) />
    <RadzenDataGrid @ref="grid" AllowFiltering="true" AllowPaging="true" PageSize="5" AllowSorting="true" RowRender="@RowRender" ExpandMode="DataGridExpandMode.Multiple"
                Data="@_orders" TItem="Order" EditMode="DataGridEditMode.Multiple" RowUpdate="@OnUpdateRow" RowCreate="@OnCreateRow">
        <Template Context="order">
            <RadzenCard Style="margin-bottom:20px">
                Company:
                <b>@order.VendorName</b>
            </RadzenCard>
            <RadzenTabs>
                <Tabs>
                    <RadzenTabsItem Text="Order Details">
                        <RadzenDataGrid AllowFiltering="true" AllowPaging="true" AllowSorting="true" Data="@(_orders.FirstOrDefault()?.OrderDetails)" TItem="OrderDetail" 
                                        EditMode="DataGridEditMode.Multiple" >
                            <Columns>
                                <RadzenDataGridColumn TItem="OrderDetail" Property="Id" Title="Product Number" />
                                <RadzenDataGridColumn TItem="OrderDetail" Property="ProductCode" Title="Code" />
                                <RadzenDataGridColumn TItem="OrderDetail" Property="ProductName" Title="Name">
                                    <Template Context="detail">
                                        @String.Format(new System.Globalization.CultureInfo("en-US"), "{0:C}",detail.UnitCost)
                                    </Template>
                                </RadzenDataGridColumn>
                                <RadzenDataGridColumn TItem="OrderDetail" Property="BuyQuantity" Title="Buy Qty" />
                                <RadzenDataGridColumn TItem="OrderDetail" Property="SellQuantity" Title="Sell Qty" />
                                <RadzenDataGridColumn TItem="OrderDetail" Property="ShippingNumber" Title="Shipment"/>
                            </Columns>
                        </RadzenDataGrid>
                    </RadzenTabsItem>
                    
                </Tabs>
            </RadzenTabs>
        </Template>
        <Columns>
            <RadzenDataGridColumn TItem="Order" Property="Id" Title="Order ID" Width="120px" />
            <RadzenDataGridColumn TItem="Order" Property="CustomerName" Title="Customer" Width="200px" />
            <RadzenDataGridColumn TItem="Order" Property="OrderDateTime" Title="Order Date" Width="200px">
                <Template Context="order">
                    @String.Format("{0:d}", order.OrderDateTime)
                </Template>
            </RadzenDataGridColumn>
            <RadzenDataGridColumn TItem="Order" Property="Status" Title="Status" Width="100px" />
            <RadzenDataGridColumn TItem="Order" Property="DoneBy" Title="Employee" />
            <RadzenDataGridColumn TItem="Order" Context="order" Filterable="false" Sortable="false" TextAlign="TextAlign.Center" Width="120px">
                <Template Context="order">
                    <RadzenButton Icon="edit" ButtonStyle="ButtonStyle.Light" Class="m-1" Click="@(args => EditRow(order))" @onclick:stopPropagation="true">
                    </RadzenButton>
                </Template>
                <EditTemplate Context="order">
                    <RadzenButton Icon="check" ButtonStyle="ButtonStyle.Primary" Class="m-1" Click="@((args) => SaveRow(order))">
                    </RadzenButton>
                    <RadzenButton Icon="close" ButtonStyle="ButtonStyle.Light" Class="m-1" Click="@((args) => CancelEdit(order))">
                    </RadzenButton>
                </EditTemplate>
            </RadzenDataGridColumn>
            <RadzenDataGridColumn TItem="Order" Context="order" Filterable="false" Sortable="false" TextAlign="TextAlign.Center" Width="60px">
                <Template Context="order">
                    <RadzenButton ButtonStyle="ButtonStyle.Danger" Icon="delete" Size="ButtonSize.Small" Class="m-1" Click="@(args => DeleteRow(order))"  @onclick:stopPropagation="true">
                    </RadzenButton>
                </Template>
                <EditTemplate Context="order">
                    <RadzenButton ButtonStyle="ButtonStyle.Danger" Icon="delete" Size="ButtonSize.Small" Class="m-1" Click="@(args => DeleteRow(order))">
                    </RadzenButton>
                </EditTemplate>
            </RadzenDataGridColumn>
        </Columns>
    </RadzenDataGrid>
@code {
   
    IEnumerable<Order> _orders = new List<Order>();
    
    RadzenDataGrid<Order> grid;
    Order orderToInsert;

    protected override async Task OnInitializedAsync()
    {
        _orders = await ViewOrdersByCustomerNameUseCase.ExecuteAsync();

    }

    void RowRender(RowRenderEventArgs<Order> args)
    {
        if(args.Data.OrderDetails != null)
            args.Expandable = args.Data.OrderDetails.Count > 0;
    }

    protected override void OnAfterRender(bool firstRender)
    {
        if (firstRender)
        {
            grid.ExpandRow(_orders.FirstOrDefault());
            StateHasChanged();
        }

        base.OnAfterRender(firstRender);
    }
    

    private async Task InsertRow()
    {
        orderToInsert = new Order();
        await grid.InsertRow(orderToInsert);
    }

    private async Task OnCreateRow(Order order)
    {
        if (order != null)
        {
            await AddOrderUseCase.ExecuteAsync(order);

        }

    
    }
    private async Task OnCreateRowDetail(Order order)
    {
        if (order != null)
        {
            await AddOrderUseCase.ExecuteAsync(order);

        }

    
    }
    private async Task OnUpdateRow(Order order)
    {
        if (order == orderToInsert)
        {
            orderToInsert = null;
        }

        if (order != null)
        {
            await EditOrderUseCase.ExecuteAsync(order);
           
        }
    }
    private async Task OnUpdateRowDetail(Order order)
    {
        if (order.OrderDetails != null)
        {
            await EditOrderUseCase.ExecuteAsync(order);
           
        }
    }

    private void CancelEdit(Order order)
    {
        if (order == orderToInsert)
        {
            orderToInsert = null;
        }

        grid.CancelEditRow(order);

    
    }

    async Task DeleteRow(Order order)
    {
        if (order == orderToInsert)
        {
            orderToInsert = null;
        }

        if (_orders.Contains(order))
        {
           await grid.Reload();
        }
        else
        {
            grid.CancelEditRow(order);
        }
    }
    async Task EditRow(Order order)
    {
        await grid.EditRow(order);
    }
    async Task SaveRow(Order order)
    {
        if (order == orderToInsert)
        {
            orderToInsert = null;
        }

        await grid.UpdateRow(order);
    }  

}

在此處輸入圖像描述 編輯 3

到目前為止,我想我已經對 Radzen 和主從網格有所了解。 但仍然需要一些幫助。

這是更新且通常可以正常工作的 Blazor:

@page "/orders"
@using IMS.CoreBusiness
@using IMS.Plugins.EFCore.Migrations
@using IMS.UseCases.Interfaces.Order
@using IMS.UseCases.Interfaces.OrderDetail


@inject NavigationManager NavigationManager
@inject IViewAllOrdersUseCase ViewAllOrdersUseCase
@inject IAddOrderUseCase AddOrderUseCase
@inject IEditOrderUseCase EditOrderUseCase
@inject IAddOrderDetailUseCase AddOrderDetailUseCase
@inject IEditOrderDetailUseCase EditOrderDetailUseCase

<h1>Orders</h1>
<RadzenButton Icon="add_circle_outline" style="margin-bottom: 10px" Text="Add New Order" Click="@InsertRow" Disabled=@(orderToInsert != null) />
    <RadzenDataGrid @ref="grid" AllowFiltering="true" AllowPaging="true" PageSize="5" AllowSorting="true" RowRender="@RowRender" ExpandMode="DataGridExpandMode.Multiple"
                Data="@_orders" TItem="Order" EditMode="DataGridEditMode.Multiple" RowUpdate="@OnUpdateRow" RowCreate="@OnCreateRow">
        <Template Context="order">
            <RadzenCard Style="margin-bottom:20px">
                Vendor:
                <b>@order.VendorName</b>
            </RadzenCard>
            <RadzenTabs>
                <Tabs>
                    <RadzenTabsItem Text="Order Details">
                        <RadzenDataGrid @ref="gridDetail" AllowFiltering="true" AllowPaging="true" PageSize="5" AllowSorting="true" Data="@(_orders.FirstOrDefault()?.OrderDetails)" 
                        TItem="OrderDetail" EditMode="DataGridEditMode.Multiple" RowUpdate="@OnUpdateRowDetail" RowCreate="@OnCreateRowDetail" RowRender="@RowRenderDetail">
                            <Columns>
                                <RadzenDataGridColumn TItem="OrderDetail" Property="Id" Title="Product Number" />
                                <RadzenDataGridColumn TItem="OrderDetail" Property="ProductCode" Title="Code" />
                                <RadzenDataGridColumn TItem="OrderDetail" Property="ProductName" Title="Name">
                                    <EditTemplate Context="orderDetail">
                                        <RadzenTextBox @bind-Value="orderDetail.ProductName" Style="width:100%; display: block" Name="ProductName" />
                                        <RadzenRequiredValidator Text="Product Name is required" Component="ProductName" Popup="true" Style="position:absolute"/>
                                    </EditTemplate>
                                </RadzenDataGridColumn>
                                <RadzenDataGridColumn TItem="OrderDetail" Property="UnitCost" Title="Unit Cost">
                                    <Template Context="detail">
                                        @String.Format(new System.Globalization.CultureInfo("en-US"), "{0:C}",detail.UnitCost)
                                    </Template>
                                </RadzenDataGridColumn>
                                <RadzenDataGridColumn TItem="OrderDetail" Property="BuyQuantity" Title="Buy Qty" />
                                <RadzenDataGridColumn TItem="OrderDetail" Property="SellQuantity" Title="Sell Qty" />
                                <RadzenDataGridColumn TItem="OrderDetail" Property="ShippingNumber" Title="Shipment"/>
                                <RadzenDataGridColumn TItem="OrderDetail" Context="order" Filterable="false" Sortable="false" TextAlign="TextAlign.Center" Width="60px">
                                    <Template Context="detail">
                                        <RadzenButton Icon="edit" ButtonStyle="ButtonStyle.Primary" Class="m-1" Click="@(args => EditRowDetail(detail))" @onclick:stopPropagation="true">
                                        </RadzenButton>
                                    </Template>
                                    <EditTemplate Context="detail">
                                        <RadzenButton Icon="check" ButtonStyle="ButtonStyle.Primary" Class="m-1" Click="@((args) => SaveRowDetail(detail))">
                                        </RadzenButton>
                                        <RadzenButton Icon="close" ButtonStyle="ButtonStyle.Light" Class="m-1" Click="@((args) => CancelEditDetail(detail))">
                                        </RadzenButton>
                                    </EditTemplate>
                                </RadzenDataGridColumn>
                            </Columns>
                        </RadzenDataGrid>
                    </RadzenTabsItem>
                    
                </Tabs>
            </RadzenTabs>
        </Template>
        <Columns>
            <RadzenDataGridColumn TItem="Order" Property="Id" Title="Order ID" Width="120px" />
            <RadzenDataGridColumn TItem="Order" Property="CustomerName" Title="Customer" Width="200px">
                <EditTemplate Context="order">
                    <RadzenTextBox @bind-Value="order.CustomerName" Style="width:100%; display: block" Name="CustomerName" />
                    <RadzenRequiredValidator Text="Customer Name is required" Component="CustomerName" Popup="true" Style="position:absolute"/>
                </EditTemplate>
            </RadzenDataGridColumn>
            <RadzenDataGridColumn TItem="Order" Property="OrderDateTime" Title="Order Date" Width="200px">
                <Template Context="order">
                    @String.Format("{0:dd/MM/yyyy}", order.OrderDateTime)
                </Template>
                <EditTemplate Context="order">
                    <RadzenDatePicker @bind-Value="order.OrderDateTime" Style="width:100%" DateFormat="d" />
                </EditTemplate>
            </RadzenDataGridColumn>
            <RadzenDataGridColumn TItem="Order" Property="Status" Title="Status" Width="100px" />
            <RadzenDataGridColumn TItem="Order" Property="DoneBy" Title="Employee">
                <EditTemplate Context="order">
                    <RadzenTextBox @bind-Value="order.DoneBy" Style="width:100%; display: block" Name="DoneBy" />
                    <RadzenRequiredValidator Text="DoneBy is required" Component="DoneBy" Popup="true" Style="position:absolute"/>
                </EditTemplate>
            </RadzenDataGridColumn>
            <RadzenDataGridColumn TItem="Order" Context="order" Filterable="false" Sortable="false" TextAlign="TextAlign.Center" Width="120px">
                <Template Context="order">
                    <RadzenButton Icon="edit" ButtonStyle="ButtonStyle.Primary" Class="m-1" Click="@(args => EditRow(order))" @onclick:stopPropagation="true">
                    </RadzenButton>
                </Template>
                <EditTemplate Context="order">
                    <RadzenButton Icon="check" ButtonStyle="ButtonStyle.Primary" Class="m-1" Click="@((args) => SaveRow(order))">
                    </RadzenButton>
                    <RadzenButton Icon="close" ButtonStyle="ButtonStyle.Light" Class="m-1" Click="@((args) => CancelEdit(order))">
                    </RadzenButton>
                </EditTemplate>
            </RadzenDataGridColumn>
            @*<RadzenDataGridColumn TItem="Order" Context="order" Filterable="false" Sortable="false" TextAlign="TextAlign.Center" Width="60px">
                <Template Context="order">
                    <RadzenButton ButtonStyle="ButtonStyle.Danger" Icon="delete" Size="ButtonSize.Small" Class="m-1" Click="@(args => DeleteRow(order))"  @onclick:stopPropagation="true">
                    </RadzenButton>
                </Template>
                <EditTemplate Context="order">
                    <RadzenButton ButtonStyle="ButtonStyle.Danger" Icon="delete" Size="ButtonSize.Small" Class="m-1" Click="@(args => DeleteRow(order))">
                    </RadzenButton>
                </EditTemplate>
            </RadzenDataGridColumn>*@
        </Columns>
    </RadzenDataGrid>
@code {

    IEnumerable<Order> _orders = new List<Order>();
    IEnumerable<OrderDetail> _orderDetails = new List<OrderDetail>();
    
    RadzenDataGrid<Order> grid;
    RadzenDataGrid<OrderDetail> gridDetail;

    Order orderToInsert;
    OrderDetail detailToInsert;

    protected override async Task OnInitializedAsync()
    {
        _orders = await ViewAllOrdersUseCase.ExecuteAsync();

    }

    void RowRender(RowRenderEventArgs<Order> args)
    {
        if(args.Data.OrderDetails != null)
            args.Expandable = args.Data.OrderDetails.Count > 0;
    }

    void RowRenderDetail(RowRenderEventArgs<OrderDetail> args)
    {
        if(args.Data != null)
            args.Expandable = true;
    }

    protected override void OnAfterRender(bool firstRender)
    {
        if (firstRender)
        {
            grid.ExpandRow(_orders.FirstOrDefault());
            StateHasChanged();
        }

        base.OnAfterRender(firstRender);
    }


    private async Task InsertRow()
    {
        orderToInsert = new Order();
        detailToInsert = new OrderDetail();
        await grid.InsertRow(orderToInsert);
        await gridDetail.InsertRow(detailToInsert);
    }

    private async Task OnCreateRow(Order order)
    {
        if (order != null)
        {
            await AddOrderUseCase.ExecuteAsync(order);

        }


    }
    private async Task OnCreateRowDetail(OrderDetail orderDetail)
    {
        if (orderDetail != null)
        {
            await AddOrderDetailUseCase.ExecuteAsync(orderDetail);

        }


    }
    private async Task OnUpdateRow(Order order)
    {
        if (order == orderToInsert)
        {
            orderToInsert = null;
        }

        if (order != null)
        {
            await EditOrderUseCase.ExecuteAsync(order);

        }
    }
    private async Task OnUpdateRowDetail(OrderDetail orderDetail)
    {
        if (orderDetail == detailToInsert)
        {
            detailToInsert = null;
        }
        if (orderDetail != null)
        {
            await EditOrderDetailUseCase.ExecuteAsync(orderDetail);

        }
    }

    private void CancelEdit(Order order)
    {
        if (order == orderToInsert)
        {
            orderToInsert = null;
        }

        grid.CancelEditRow(order);


    }
    private void CancelEditDetail(OrderDetail orderDetail)
    {
        if (orderDetail == detailToInsert)
        {
            detailToInsert = null;
        }

        gridDetail.CancelEditRow(orderDetail);


    }

    async Task DeleteRow(Order order)
    {
        if (order == orderToInsert)
        {
            orderToInsert = null;
        }

        if (_orders.Contains(order))
        {
            await grid.Reload();
        }
        else
        {
            grid.CancelEditRow(order);
        }
    }

    async Task DeleteRowDetail(OrderDetail orderDetail)
    {
        if (orderDetail == detailToInsert)
        {
            detailToInsert = null;
        }


        if (_orders.All(x=>x.OrderDetails.Contains(orderDetail)))
        {
            await gridDetail.Reload();
        }
        else
        {
            gridDetail.CancelEditRow(orderDetail);
        }
    }
    async Task EditRow(Order order)
    {
        await grid.EditRow(order);
    }

    async Task EditRowDetail(OrderDetail orderDetail)
    {
        await gridDetail.EditRow(orderDetail);
    }
    async Task SaveRow(Order order)
    {
        if (order == orderToInsert)
        {
            orderToInsert = null;
        }

        await grid.UpdateRow(order);
    }

    async Task SaveRowDetail(OrderDetail orderDetail)
    {
        if (orderDetail == detailToInsert)
        {
            detailToInsert = null;
        }

        await gridDetail.UpdateRow(orderDetail);
    }
   

}

為了成功,我希望您能支持以下問題。

  1. 嘗試添加新行時,我不希望日期(1.01.0001)只是日歷圖標。 在此處輸入圖像描述
  2. 為什么單擊內部網格編輯按鈕時沒有取消按鈕? 在此處輸入圖像描述
  3. 當我單擊“添加新行”時,為什么不在內部網格中添加新行? 在此處輸入圖像描述

以下是問題修復代碼:

@page "/orders"
@using IMS.CoreBusiness
@using IMS.Plugins.EFCore.Migrations
@using IMS.UseCases.Interfaces.Order
@using IMS.UseCases.Interfaces.OrderDetail


@inject NavigationManager NavigationManager
@inject IViewAllOrdersUseCase ViewAllOrdersUseCase
@inject IAddOrderUseCase AddOrderUseCase
@inject IEditOrderUseCase EditOrderUseCase
@inject IAddOrderDetailUseCase AddOrderDetailUseCase
@inject IEditOrderDetailUseCase EditOrderDetailUseCase

<h1>Orders</h1>
<RadzenButton Icon="add_circle_outline" style="margin-bottom: 10px" Text="Add New Order" Click="@InsertRow" Disabled=@(orderToInsert != null) />
    <RadzenDataGrid @ref="grid" AllowFiltering="true" AllowPaging="true" PageSize="5" AllowSorting="true" RowRender="@RowRender" ExpandMode="DataGridExpandMode.Multiple"
                Data="@_orders" TItem="Order" EditMode="DataGridEditMode.Multiple" RowUpdate="@OnUpdateRow" RowCreate="@OnCreateRow" @bind-Value="@SelectedOrders">
        <Template Context="order">
            <RadzenCard Style="margin-bottom:20px">
                Vendor:
                <b>@order.VendorName</b>
            </RadzenCard>
            <RadzenTabs>
                <Tabs>
                    <RadzenTabsItem Text="Order Details">
                        <RadzenButton Icon="add_circle_outline" style="margin-bottom: 10px" Text="Add Order Detail" Click="@InsertDetailRow" Disabled=@(detailToInsert != null) />
                        <RadzenDataGrid @ref="gridDetail" AllowFiltering="true" AllowPaging="true" PageSize="5" AllowSorting="true" Data="@(SelectedOrders.FirstOrDefault()?.OrderDetails)" 
                        TItem="OrderDetail" EditMode="DataGridEditMode.Multiple" RowUpdate="@OnUpdateRowDetail" RowCreate="@OnCreateRowDetail" RowRender="@RowRenderDetail">
                            <Columns>
                                <RadzenDataGridColumn TItem="OrderDetail" Property="Id" Title="Product Number" />
                                <RadzenDataGridColumn TItem="OrderDetail" Property="ProductCode" Title="Code">
                                    <EditTemplate Context="orderDetail">
                                        <RadzenTextBox @bind-Value="orderDetail.ProductCode" Style="width:100%; display: block" Name="ProductCode" />
                                        <RadzenRequiredValidator Text="Product Code is required" Component="ProductCode" Popup="true" Style="position:absolute"/>
                                    </EditTemplate>
                                </RadzenDataGridColumn>
                                <RadzenDataGridColumn TItem="OrderDetail" Property="ProductName" Title="Name">
                                    <EditTemplate Context="orderDetail">
                                        <RadzenTextBox @bind-Value="orderDetail.ProductName" Style="width:100%; display: block" Name="ProductName" />
                                        <RadzenRequiredValidator Text="Product Name is required" Component="ProductName" Popup="true" Style="position:absolute"/>
                                    </EditTemplate>
                                </RadzenDataGridColumn>
                                <RadzenDataGridColumn TItem="OrderDetail" Property="UnitCost" Title="Unit Cost">
                                    <Template Context="detail">
                                        @String.Format(new System.Globalization.CultureInfo("en-US"), "{0:C}",detail.UnitCost)
                                    </Template>
                                    @*<EditTemplate Context="orderDetail">
                                        <RadzenNumeric ShowUpDown="false" TValue="double?" @bind-Value="orderDetail.UnitCost" Class="w-100" />
                                        @*<RadzenTextBox @bind-Value="orderDetail.UnitCost" Style="width:100%; display: block" Name="UnitCost" />
                                        <RadzenRequiredValidator Text="Unit Cost is required" Component="UnitCost" Popup="true" Style="position:absolute"/>
                                    </EditTemplate>*@
                                </RadzenDataGridColumn>
                                <RadzenDataGridColumn TItem="OrderDetail" Property="BuyQuantity" Title="Buy Qty" />
                                <RadzenDataGridColumn TItem="OrderDetail" Property="SellQuantity" Title="Sell Qty" />
                                <RadzenDataGridColumn TItem="OrderDetail" Property="ShippingNumber" Title="Shipment"/>
                                <RadzenDataGridColumn TItem="OrderDetail" Context="orderDetail" Filterable="false" Sortable="false" TextAlign="TextAlign.Center" Width="120px">
                                    <Template Context="detail">
                                        <RadzenButton Icon="edit" ButtonStyle="ButtonStyle.Primary" Class="m-1" Click="@(args => EditRowDetail(detail))" @onclick:stopPropagation="true">
                                        </RadzenButton>
                                    </Template>
                                    <EditTemplate Context="detail">
                                        <RadzenButton Icon="check" ButtonStyle="ButtonStyle.Primary" Class="m-1" Click="@((args) => SaveRowDetail(detail))">
                                        </RadzenButton>
                                        <RadzenButton Icon="close" ButtonStyle="ButtonStyle.Light" Class="m-1" Click="@((args) => CancelEditDetail(detail))">
                                        </RadzenButton>
                                    </EditTemplate>
                                </RadzenDataGridColumn>
                            </Columns>
                        </RadzenDataGrid>
                    </RadzenTabsItem>
                    
                </Tabs>
            </RadzenTabs>
        </Template>
        <Columns>
            <RadzenDataGridColumn TItem="Order" Property="Id" Title="Order ID" Width="120px" />
            <RadzenDataGridColumn TItem="Order" Property="CustomerName" Title="Customer" Width="200px">
                <EditTemplate Context="order">
                    <RadzenTextBox @bind-Value="order.CustomerName" Style="width:100%; display: block" Name="CustomerName" />
                    <RadzenRequiredValidator Text="Customer Name is required" Component="CustomerName" Popup="true" Style="position:absolute"/>
                </EditTemplate>
            </RadzenDataGridColumn>
            <RadzenDataGridColumn TItem="Order" Property="OrderDateTime" Title="Order Date" Width="200px">
                <Template Context="order">
                    @String.Format("{0:dd/MM/yyyy}", order.OrderDateTime)
                </Template>
                <EditTemplate Context="order">
                    <RadzenDatePicker TValue="DateTime?" DateFormat="dd/MM/yyyy HH:mm" Class="w-100" />
                    @*<RadzenDatePicker @bind-Value="order.OrderDateTime" Style="width:100%" DateFormat="d" />*@
                </EditTemplate>
            </RadzenDataGridColumn>
            <RadzenDataGridColumn TItem="Order" Property="Status" Title="Status" Width="100px">
                <EditTemplate Context="order">
                    <RadzenTextBox @bind-Value="order.Status" Style="width:100%; display: block" Name="Status" />
                    <RadzenRequiredValidator Text="Status is required" Component="Status" Popup="true" Style="position:absolute"/>
                </EditTemplate>
            </RadzenDataGridColumn>
            <RadzenDataGridColumn TItem="Order" Property="DoneBy" Title="Employee">
                <EditTemplate Context="order">
                    <RadzenTextBox @bind-Value="order.DoneBy" Style="width:100%; display: block" Name="DoneBy" />
                    <RadzenRequiredValidator Text="DoneBy is required" Component="DoneBy" Popup="true" Style="position:absolute"/>
                </EditTemplate>
            </RadzenDataGridColumn>
            <RadzenDataGridColumn TItem="Order" Context="order" Filterable="false" Sortable="false" TextAlign="TextAlign.Center" Width="120px">
                <Template Context="order">
                    <RadzenButton Icon="edit" ButtonStyle="ButtonStyle.Primary" Class="m-1" Click="@(args => EditRow(order))" @onclick:stopPropagation="true">
                    </RadzenButton>
                </Template>
                <EditTemplate Context="order">
                    <RadzenButton Icon="check" ButtonStyle="ButtonStyle.Primary" Class="m-1" Click="@((args) => SaveRow(order))">
                    </RadzenButton>
                    <RadzenButton Icon="close" ButtonStyle="ButtonStyle.Light" Class="m-1" Click="@((args) => CancelEdit(order))">
                    </RadzenButton>
                </EditTemplate>
            </RadzenDataGridColumn>
            @*<RadzenDataGridColumn TItem="Order" Context="order" Filterable="false" Sortable="false" TextAlign="TextAlign.Center" Width="60px">
                <Template Context="order">
                    <RadzenButton ButtonStyle="ButtonStyle.Danger" Icon="delete" Size="ButtonSize.Small" Class="m-1" Click="@(args => DeleteRow(order))"  @onclick:stopPropagation="true">
                    </RadzenButton>
                </Template>
                <EditTemplate Context="order">
                    <RadzenButton ButtonStyle="ButtonStyle.Danger" Icon="delete" Size="ButtonSize.Small" Class="m-1" Click="@(args => DeleteRow(order))">
                    </RadzenButton>
                </EditTemplate>
            </RadzenDataGridColumn>*@
        </Columns>
    </RadzenDataGrid>
@code {
    IList<Order> SelectedOrders { get; set; }

    IEnumerable<Order> _orders = new List<Order>();

    RadzenDataGrid<Order> grid;
    RadzenDataGrid<OrderDetail> gridDetail;

    Order orderToInsert;
    OrderDetail detailToInsert;

    protected override async Task OnInitializedAsync()
    {
        _orders = await ViewAllOrdersUseCase.ExecuteAsync();
        SelectedOrders = new List<Order>(){ _orders.FirstOrDefault() };

    }

    void RowRender(RowRenderEventArgs<Order> args)
    {
        if(args.Data.OrderDetails != null)
            args.Expandable = args.Data.OrderDetails.Count > 0;
    }

    void RowRenderDetail(RowRenderEventArgs<OrderDetail> args)
    {
        if(args.Data != null)
            args.Expandable = true;
    }

    protected override void OnAfterRender(bool firstRender)
    {
        if (firstRender)
        {
            grid.ExpandRow(_orders.FirstOrDefault());
            StateHasChanged();
        }

        base.OnAfterRender(firstRender);
    }


    private async Task InsertRow()
    {
        orderToInsert = new Order();
        await grid.InsertRow(orderToInsert);
        
    }
    private async Task InsertDetailRow()
    {
        detailToInsert = new OrderDetail();
        await gridDetail.InsertRow(detailToInsert);
    }

    private async Task OnCreateRow(Order order)
    {
        if (order != null)
        {
            await AddOrderUseCase.ExecuteAsync(order);

        }


    }
    private async Task OnCreateRowDetail(OrderDetail orderDetail)
    {
        if (orderDetail != null)
        {
            await AddOrderDetailUseCase.ExecuteAsync(orderDetail);

        }


    }
    private async Task OnUpdateRow(Order order)
    {
        if (order == orderToInsert)
        {
            orderToInsert = null;
        }

        if (order != null)
        {
            await EditOrderUseCase.ExecuteAsync(order);

        }
    }
    private async Task OnUpdateRowDetail(OrderDetail orderDetail)
    {
        if (orderDetail == detailToInsert)
        {
            detailToInsert = null;
        }
        if (orderDetail != null)
        {
            await EditOrderDetailUseCase.ExecuteAsync(orderDetail);

        }
    }

    private void CancelEdit(Order order)
    {
        if (order == orderToInsert)
        {
            orderToInsert = null;
        }

        grid.CancelEditRow(order);


    }
    private void CancelEditDetail(OrderDetail orderDetail)
    {
        if (orderDetail == detailToInsert)
        {
            detailToInsert = null;
        }

        gridDetail.CancelEditRow(orderDetail);


    }

    async Task DeleteRow(Order order)
    {
        if (order == orderToInsert)
        {
            orderToInsert = null;
        }

        if (_orders.Contains(order))
        {
            await grid.Reload();
        }
        else
        {
            grid.CancelEditRow(order);
        }
    }

    async Task DeleteRowDetail(OrderDetail orderDetail)
    {
        if (orderDetail == detailToInsert)
        {
            detailToInsert = null;
        }


        if (_orders.All(x=>x.OrderDetails.Contains(orderDetail)))
        {
            await gridDetail.Reload();
        }
        else
        {
            gridDetail.CancelEditRow(orderDetail);
        }
    }
    async Task EditRow(Order order)
    {
        await grid.EditRow(order);
    }

    async Task EditRowDetail(OrderDetail orderDetail)
    {
        await gridDetail.EditRow(orderDetail);
    }
    async Task SaveRow(Order order)
    {
        if (order == orderToInsert)
        {
            orderToInsert = null;
        }

        await grid.UpdateRow(order);
    }

    async Task SaveRowDetail(OrderDetail orderDetail)
    {
        if (orderDetail == detailToInsert)
        {
            detailToInsert = null;
        }

        await gridDetail.UpdateRow(orderDetail);
    }
   

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM