65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 EF 和 Web API 实现 ASP.NET Core Blazor 主从表格(含筛选和排序)

starIconstarIconstarIconstarIconstarIcon

5.00/5 (4投票s)

2018年6月10日

CPOL

14分钟阅读

viewsIcon

41341

downloadIcon

824

本文将介绍如何使用 Entity Framework 和 Web API,使用 ASP.NET Core Blazor 创建自定义的主从 HTML 表格,并实现排序和筛选功能。我们还将利用 Blazor 的动态内容功能来创建主从表。

引言

* 欢迎观看我的 YouTube 视频教程,学习 使用 Entity Framework 和 Web API 实现 ASP.NET Core Blazor 主从表

本文将介绍如何使用 Entity Framework 和 Web API,使用 ASP.NET Core Blazor 创建自定义的主从 HTML 表格,并实现排序和筛选功能。我们还将利用 Blazor 的动态内容功能来创建主从表。

请阅读我之前的文章,深入了解 ASP.NET Core Blazor 入门。

本文将讲解

  1. 创建示例数据库和 SQL Server 中的 `Student` 主表和明细表,用于在我们的 Web 应用程序中显示
  2. 如何创建 ASP.NET Core Blazor Web 应用程序
  3. 如何安装 Entity Framework 所需的包并创建 `DBContext` 类
  4. 如何从 Web API 获取结果并绑定到 Blazor 客户端的 Razor 视图
  5. 创建具有排序和筛选功能的主/从 HTML 表格
  6. 使用 Blazor 动态内容创建主/从表格

Blazor 动态内容

在 Blazor 中,我们可以使用 C# 代码编写自己的组件。我们都知道,在 Blazor 中,我们可以在客户端 HTML 函数部分编写 C# 代码。有时,我们需要动态地创建并将结果绑定到 HTML 页面。在本文中,我们将使用 Blazor 动态内容,在运行时动态创建明细表,并在用户单击主表中的明细显示图标时进行显示。

我们也可以称之为:主/从 HTML 表格、分层表格或嵌套表格。

为什么需要嵌套表格、分层表格或主/从表格?

在实际项目中,例如订单管理、生产管理、学生管理等,我们需要以分层结构显示数据。

例如,我们以大学的 `Students` 管理项目为例。对于 `students` 管理,我们需要创建许多关联表,例如 `Student Master`(学生主表)和 `Student Details`(学生明细表)等。在 `Student Master` 中,我们存储 `student ID`、`Name`(姓名)、`Email`(电子邮件)、`Phone`(电话)和 `Address`(地址)。在 `Student Details` 中,我们存储 `student` 的期末考试成绩,用于显示 `Student Major`(学生专业)、`Studying Year with Term`(学年与学期)和 `Grade details`(成绩详情)。这两个表都将通过 `StudentID` 相关联。我们将这两个表连接起来,以显示完整的学生详细信息。

最初,我们将所有 `students` 的主记录显示在 HTML 表格中供查看。用户可以单击每个 `student` 旁边的展开图标来查看其完整详细信息。

在这里,下图显示了我们将 `Student Master` 和 `Student detail` 的结果都绑定到 HTML 表格中,并且只有当用户单击主表 `StudentID` 旁边的图标时才显示明细。当用户单击 `StudentID` “`2”时,下一个明细 `Grid` 将被显示,以 `Major`(专业)、`Year`(年级)、`Term`(学期)和 `Grade`(成绩)来显示 `student` 的成绩明细。

在这里,我们按每个 `student Id` 显示 `student` 的详细信息。

在我们的示例中,我们还为我们的主/从表格添加了筛选和排序功能。

背景

请确保您的计算机已安装所有先决条件。如果没有,请逐一下载并安装。请注意,由于 Blazor 是一个新框架,我们必须安装 Visual Studio 2017 (15.7) 或更高版本的预览版。

Using the Code

步骤 1 - 创建数据库和表

我们将使用我们的 SQL Server 数据库来为 WEB API 和 EF 做准备。首先,我们创建一个名为 `StudentsDB` 的数据库和一个名为 `StudentMaster` 的表。以下是用于在我们的项目中创建数据库表和插入示例记录的 SQL 脚本。请在您的本地 SQL Server 中运行以下查询,以创建数据库和表。

USE MASTER 
GO 
--1) Check 
--  for the Database Exists.If the database is exist then drop and create new DB 
IF EXISTS(SELECT [name] FROM sys.databases WHERE[name] = 'StudentGradeDB') 
DROP DATABASE StudentGradeDB 
GO 
CREATE DATABASE StudentGradeDB 
GO 
USE StudentGradeDB 
GO 
--1) //////////// StudentMasters 
 
CREATE TABLE[dbo].[StudentMasters]( 
        [StdID] INT IDENTITY PRIMARY KEY,
   [StdName][varchar](100) NOT NULL,
    [Email][varchar](100) NOT NULL,
    [Phone][varchar](20) NOT NULL,
    [Address][varchar](200) NOT NULL
    ) 
    --insert sample data to Student Master table 
INSERT INTO [StudentMasters]([StdName], [Email], [Phone], [Address]) 
  VALUES('Shanu', <a href="mailto:'syedshanumcain@gmail.com'">'syedshanumcain@gmail.com'</a>, 
         '01030550007', 'Madurai,India') 
INSERT INTO [StudentMasters]([StdName], [Email], [Phone], [Address]) 
  VALUES('Afraz', <a href="mailto:'Afraz@afrazmail.com'">'Afraz@afrazmail.com'</a>, 
         '01030550006', 'Madurai,India') 
INSERT INTO [StudentMasters]([StdName], [Email], [Phone], [Address]) 
  VALUES('Afreen', <a href="mailto:'Afreen@afreenmail.com'">'Afreen@afreenmail.com'</a>, 
                    '01030550005', 'Madurai,India') 

select * from[StudentMasters] 

 --1) //////////// StudentDetails 
CREATE TABLE[dbo].[StudentDetails]( 
    [StdDtlID] INT IDENTITY PRIMARY KEY, [StdID] INT,
 [Major][varchar](100) NOT NULL,
  [Year][varchar](30) NOT NULL,
  [Term][varchar](30) NOT NULL,
   [Grade][varchar](10) NOT NULL)
    
INSERT INTO[StudentDetails]([StdID], [Major], [Year], [Term], [Grade]) 
  VALUES(1, 'Computer Science', 'FirstYear', 'FirstTerm', 'A') 
INSERT INTO[StudentDetails]([StdID], [Major], [Year], [Term], [Grade]) 
  VALUES(1, 'Computer Science', 'FirstYear', 'SecondTerm', 'B') 
INSERT INTO[StudentDetails]([StdID], [Major], [Year], [Term], [Grade]) 
  VALUES(1, 'Computer Science', 'SecondYear', 'FirstTerm', 'C') 
INSERT INTO[StudentDetails]([StdID], [Major], [Year], [Term], [Grade]) 
  VALUES(2, 'Computer Engineer', 'ThirdYear', 'FirstTerm', 'A') 
INSERT INTO[StudentDetails]([StdID], [Major], [Year], [Term], [Grade]) 
  VALUES(2, 'Computer Engineer', 'ThirdYear', 'SecondTerm', 'A') 
INSERT INTO[StudentDetails]([StdID], [Major], [Year], [Term], [Grade]) 
  VALUES(3, 'English', 'First Year', 'FirstTerm', 'C') 
INSERT INTO[StudentDetails]([StdID], [Major], [Year], [Term], [Grade]) 
  VALUES(3, 'Economics', 'First Year', 'FirstTerm', 'A') 

select * from StudentDetails

步骤 2 - 创建 ASP.NET Core Blazor 应用程序

在安装了上述所有先决条件和 ASP.NET Core Blazor Language Services 后,在您的桌面上单击“开始”>>“程序”>>“Visual Studio 2017”>>“Visual Studio 2017”。单击“新建”>>“项目”。选择“Web”>>“ASP.NET Core Angular Web Application”。输入您的项目名称,然后单击“确定”。

选择 Blazor (ASP.NET Core hosted),然后单击“确定”。

创建 ASP.NET Core Blazor 应用程序后,请等待几秒钟。您将在解决方案资源管理器中看到以下结构。

ASP.NET Core Blazor 解决方案有什么新内容?

当我们创建新的 ASP.NET Core Blazor 应用程序时,我们可以看到解决方案资源管理器中会自动创建 3 个项目。

客户端项目

创建的第一个项目是客户端项目,它将命名为 `Solutionname.Client`。在这里,我们可以看到我们的 `Solutionname` 是“`BlazorASPCORE”。项目名为客户端,此项目主要专注于所有客户端视图。在这里,我们将添加所有要在客户端浏览器中显示的页面视图。

我们可以看到已经添加了一些示例页面,并且还有一个共享文件夹,它与我们的 MVC 应用程序中的共享文件夹和布局页面(用于主页面)类似。在 Blazor 中,我们有 `MainLayout`,它将像主页面一样工作,还有 `NavMenu` 用于显示左侧菜单。

服务器项目

顾名思义,此项目将用作服务器项目。此项目主要用于创建所有控制器和 WEB API 控制器,以执行所有业务逻辑并通过 WEB API 执行 CRUD 操作。在我们的演示应用程序中,我们将在服务器项目中添加一个 Web API,并在我们的客户端应用程序中添加所有 WEB API。此服务器项目将用于从数据库获取/设置数据,并且从我们的客户端项目,我们将绑定或将结果发送到此服务器以在数据库中执行 CRUD 操作。

共享项目

顾名思义,此项目充当共享项目。此项目将作为服务器项目和客户端项目的模型。在此共享项目中声明的模型将在服务器项目和客户端项目中使用。我们还在项目所需的此处安装所有包,例如,要使用 Entity Framework,我们将所有包安装在此共享项目中。

运行以测试应用程序

当我们运行应用程序时,我们可以看到左侧是导航,右侧包含数据。我们可以看到 Blazor 网站中显示的默认示例页面和菜单。我们可以使用这些页面,或者删除它们并从我们自己的页面开始。

现在,让我们看看如何添加新页面以执行 CRUD 操作来维护 `student` 详细信息。

使用 Entity Framework

要在我们的 Blazor 应用程序中使用 Entity Framework,我们需要安装以下包。

安装包

转到“工具”,然后选择 ->“NuGet 包管理器” ->“程序包管理器控制台”。

您将在 VS 2017 IDE 的底部看到控制台。在控制台上的组合框的右侧,选择默认项目为您的共享项目“选择共享”。

  1. 您将看到 PM>,然后复制并粘贴下面的行以安装数据库提供程序包。此包用于将数据库提供程序设置为 SQL Server。

    Install-Package Microsoft.EntityFrameworkCore.SqlServer

    我们可以看到包已安装在我们的共享文件夹中。

    安装 Entity Framework

  2. 您将看到 PM>,然后复制并粘贴下面的行以安装 EF 包。
    Install-Package Microsoft.EntityFrameworkCore.Tools

    创建 DB Context 并设置 DB 连接字符串

  3. 您将看到 PM>,然后复制并粘贴下面的行来设置连接字符串并创建 DB Context。这是重要部分,因为我们提供了 SQL Server 名称、数据库名称以及 SQL server UID 和 SQL Server Password 以连接到我们的数据库以显示我们的主/从表格。我们还提供了我们的两个 SQL 表名称“`StudentMasters, `StudentDetails”来创建我们共享项目中的 `Model` 类。
    Scaffold-DbContext "Server= ServerName;Database=StudentGradeDB;
    user id=UserID;password=Password;Trusted_Connection=True;MultipleActiveResultSets=true" 
    Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Tables StudentMasters,StudentDetails

    按 Enter 创建连接字符串、模型类和数据库上下文。

    我们将在我们的共享项目中看到 `StudentMasters` 和 `StudentDetails Model` 类以及 `StudentGradeDBContext` 类。我们将在我们的服务器项目中继续使用此 `Model` 和 `DBContext` 来创建 Web API 以执行 CRUD 操作。

为获取学生详细信息创建 Web API

要创建我们的 WEB API 控制器,请右键单击“Controllers”文件夹。单击“添加新控制器”。

在这里,我们将使用 `Scaffold` 方法来创建我们的 WEB API。我们选择“带有操作的 API 控制器,使用 Entity Framework”。

从共享项目中选择我们的 `Model` 和 `DatabaseContext`。

从共享项目中选择我们的 `StudentMasters` 模型。

将数据上下文类选择为共享项目中的 `StudentsDBContext`。如果需要,我们的 `Controller` 名称将自动添加,您可以更改它并单击“添加”。

我们将仅使用 Web API 的 `Get` 方法。

与此类似,我们也为 `StudentDetails` 创建了一个 Web API。

要测试 `Get` 方法,我们可以运行我们的项目并复制 `GET` 方法的 API 路径。在这里,我们可以看到获取 _api/StudentMasters/_ 的 API 路径。

运行程序并粘贴 API 路径以测试我们的输出。

对于 `StudentDetails`,我们可以传递 `Student ID` 来获取单个 `student` 的详细信息。在这里,我们可以看到 `student ID` 为“`1”的结果,我们调用 Web API _/api/StudentDetails/1_。

现在,我们将从我们 `Client` 项目的 Razor 视图页面中绑定所有这些 WEB API 的 Json 结果,以显示主/从 HTML 表格。

处理客户端项目

注意:在本文中,我们将创建 2 个 Razor 页面。在一个 Razor 页面中,我们将创建主从 HTML 表格,并使用常规绑定方法;在另一个 Razor 页面中,我们将使用 Blazor 动态内容绑定明细表。

具有常规绑定的 Razor 页面

首先,我们需要添加新的 Razor 视图页面。

添加 Razor 视图

要添加 Razor 视图页面,请右键单击客户端项目中的 _Pages_ 文件夹。单击“添加”>>“新建项”。

选择 Razor View >> 输入您的页面名称。在这里,我们将其命名为 _Students.chtml_。

在 Razor 视图页面中,代码有 3 部分:首先是导入部分,我们在这里导入所有要在视图中使用的引用和模型;其次是 HTML 设计和数据绑定部分;最后是函数部分,用于调用所有 Web API 以绑定到我们的 HTML 页面,并执行要在视图页面中显示的客户端业务逻辑。

导入部分

首先,我们在 Razor 视图页面中导入所有必需的支持文件和引用。在这里,我们首先导入我们要在视图中使用的 `Model` 类,并导入 `HTTPClient` 以调用 Web API 来执行 CRUD 操作。

@using BLAZORASPCORE.Shared
@using BLAZORASPCORE.Shared.Models
@page "/Students"
@using Microsoft.AspNetCore.Blazor.Browser.Interop
@inject HttpClient Http

主 HTML 表格数据绑定部分

接下来,我们设计 `Student` 页面,将 Web API 返回的 `student Master` 和 `Student Detail` 结果绑定到 HTML 表格。

绑定学生主详细信息

在 `Init` 方法中,我们从 Web API 获取学生主详细信息,并使用 `foreach` 循环将结果绑定到 HTML 表格。在这里,我们绑定 `Student Master` 表格的结果,并在每行的第一个单元格中添加切换图标。在切换图标的单击事件中,我们调用 `getStudentsDetails(studentsID)` 方法来显示相关 `Student` 的 `Detail` HTML 表格。我们将 `Student ID` 传递给函数,获取相关的 `student` 详细信息,并将结果绑定到明细表格。此外,我们只在单击切换图标按钮时显示明细表格,如果再次单击切换按钮,则隐藏明细表格。

@foreach (var StudentMasters in stdMaster)
        {
            <tr style="border-style:dashed;border-width:2px;
             border-color: @(StudentMasters.StdId == studentIDs ? "#ff6a00": "#a2aabe")">
                <td align="center" style="border: solid1px#659EC7; padding: 5px;table-layout:fixed;">

                    @if (@StudentMasters.StdId == studentIDs)
                    {
                        <img src="@Imagename" onclick="@(async () => 
                                    await getStudentsDetails(@StudentMasters.StdId))" />
                    }
                    else
                    {
                        <img src="Images/toggle.png" onclick="@(async () => 
                                   await getStudentsDetails(@StudentMasters.StdId))" />

                    }

                </td>
                <td align="center">

                    <span style="color:#9F000F">
                        @StudentMasters.StdId
                    </span>
                </td>
                <td align="center">
                    <span style="color:#9F000F">
                        @StudentMasters.StdName
                    </span>
                </td>
                <td align="center">
                    <span style="color:#9F000F">
                        @StudentMasters.Email
                    </span>
                </td>
                <td align="center">
                    <span style="color:#9F000F">
                        @StudentMasters.Phone
                    </span>
                </td>
                <td align="center">
                    <span style="color:#9F000F">
                        @StudentMasters.Address
                    </span>
                </td>
            </tr>

在表头添加排序功能

在这里,我们只为主 HTML 表格添加了排序和筛选功能。如果需要,我们也可以为明细表格实现相同的功能。

在主表格的表头部分,每个表头都添加了排序图标。在排序图标按钮的单击事件中,我们调用排序函数,并将每个排序列名传递给单击事件。在函数代码部分,我们对 Web API 进行排序,并按每个列标题的排序图标单击进行升序和降序显示结果。

<table style="background-color:#FFFFFF; border-style:inset;border-width:1px;
border-color:#6D7B8D; padding:2px;width:100%;table-layout:fixed;" cellpadding="1" cellspacing="1">
        <tr style="background-color:#2d364d ; color:#FFFFFF ;border-style:dashed;
         border-width:2px;border-color:0A2464;" >
            <td width="30" align="center"></td>
            <td width="80" align="center">
                <img src="@ImageSortname" onclick="@(async () => await StudentSorting("StdId"))" 
                 height="24" width="24"/>
                Student ID
              
            </td>
            <td width="240" align="center">
                <img src="@ImageSortname" onclick="@(async () => await StudentSorting("StdName"))" 
                 height="24" width="24"/>  
                Student Name 
            </td>
            <td width="240" align="center">
                <img src="@ImageSortname" onclick="@(async () => await StudentSorting("Email"))" 
                 height="24" width="24"/>
                Email
            </td>
            <td width="120" align="center">
                <img src="@ImageSortname" onclick="@(async () => await StudentSorting("Phone"))" 
                 height="24" width="24"/>
                Phone
            </td>
            <td width="340" align="center">
                <img src="@ImageSortname" onclick="@(async () => await StudentSorting("Address"))" 
                 height="24" width="24"/>
                Address
            </td>
        </tr>

在表头添加筛选功能

在表头部分,我们添加了一个新行。在新行中,我们在每个列中添加 `Textbox` 来对绑定的结果进行筛选。在 `Textbox` 的 `onChange` 事件中,我们调用方法来执行代码函数部分的筛选操作。

<tr style="height: 30px; background-color:#336699 ; color:#FFFFFF ;">
            <td width="30" align="center"></td>
            <td width="80" align="center">Filter : </td>
            <td width="240" align="center">
                <input width="70" <a href="mailto:onchange=@OnstdNameChanged">
                 onchange=@OnstdNameChanged</a> oninput="(this.dispatchEvent(new CustomEvent
                 ('change', {bubbles: true})))" />
            </td>
            <td width="240" align="center">
                <input width="70" <a href="mailto:onchange=@OnEmailChanged">
                 onchange=@OnEmailChanged</a> oninput="(this.dispatchEvent(new CustomEvent
                 ('change', {bubbles: true})))" />
            </td>
            <td width="120" align="center">
                <input width="70" <a href="mailto:onchange=@OnPhoneChanged">
                 onchange=@OnPhoneChanged</a> oninput="(this.dispatchEvent(new CustomEvent
                 ('change', {bubbles: true})))" />
            </td>
            <td width="340" align="center">
                <input width="70" <a href="mailto:onchange=@OnAddressChanged">
                 onchange=@OnAddressChanged</a> oninput="(this.dispatchEvent(new CustomEvent
                 ('change', {bubbles: true})))" />
            </td>
        </tr>

绑定明细表格结果

首先,我们检查 `StudentDetails` 结果是否为 `null`。如果不为 `null`,则将结果绑定到 HTML 表格。在绑定结果之前,我们还检查 `showDetailStatus ==1`,这意味着显示或隐藏明细表格。默认情况下,我们将 `showDetailStatus` 设置为 `0`,并在主表格切换图标单击事件中将其更改为 `1`。如果 `showDetailStatus` 为 `1`,则显示明细表格,我们还会检查主表格 `StudentsID` 与学生明细,并将结果绑定到明细表格。

   @if (stdDetail != null)
            {
                @if (showDetailStatus == 1)
                {
                    @if (@StudentMasters.StdId == studentIDs)
                    {
                        <tr style="background-color:#6D7B8D ; color:honeydew ;
                         border-style:dashed;border-width:2px;border-color:#ECF3F4;">
                            <td colspan="6" align="center">
                                Student Details of  Student Id - <strong>@StudentMasters.StdId </strong>,
                                Total @stdDetail.Length Grade details for this Student
                            </td>
                        </tr>
                        <tr>
                            <td></td>
                            <td colspan="5">

                                <table style="background-color:#ECF3F4;border-style:dashed;
                                 border-width:2px;border-color:#0A2464; padding:5px;width:100%;
                                 table-layout:fixed;" cellpadding="1" cellspacing="1">
                                    <tr style="background-color:#659EC7 ; color:#FFFFFF ;
                                     border-style:dashed;border-width:2px;border-color:0A2464;">
                                        <td width="160" align="center">
                                            <Strong>Student Detail</Strong>
                                        </td>
                                        <td width="240" align="center">
                                            Major
                                        </td>
                                        <td width="240" align="center">
                                            Year
                                        </td>
                                        <td width="120" align="center">
                                            Term
                                        </td>
                                        <td width="340" align="center">
                                            Grade
                                        </td>
                                    </tr>
                                    @foreach (var stdDtls in stdDetail)
                                    {
                                        <tr>
                                            <td align="center">
                                                @stdDtls.StdDtlId
                                            </td>
                                            <td align="center">

                                                <span style="color:#9F000F">
                                                    @stdDtls.Major
                                                </span>
                                            </td>
                                            <td align="center">
                                                <span style="color:#9F000F">
                                                    @stdDtls.Year
                                                </span>
                                            </td>
                                            <td align="center">
                                                <span style="color:#9F000F">
                                                    @stdDtls.Term
                                                </span>
                                            </td>
                                            <td align="center">
                                                <span style="color:#9F000F">
                                                    @stdDtls.Grade
                                                </span>
                                            </td>
                                        </tr>
                                    }

                                </table>

                            </td>
                        </tr>
                    }
                }
            }

函数部分

函数部分用于调用所有 Web API 以绑定到我们的 HTML 页面,并执行要在视图页面中显示的客户端业务逻辑。

Init 方法

在 `Init` 方法中,我们获取 `student` 详细信息的 Web API 结果,并将其存储在 `StudentMaster` 对象中。我们使用此对象通过 `foreach` 语句将其绑定到我们的 HTML 表格。

@functions {
    StudentMasters[] stdMaster;
    StudentDetails[] stdDetail;

    StudentMasters stdmst = new StudentMasters();
    StudentDetails stdDtl = new StudentDetails();


    int showDetailStatus = 0;
    int sortStatus = 0;
    int studentIDs = 0;
    string Imagename = "Images/toggle.png";
    string ImageSortname = "Images/sortAsc.png";

    protected override async Task OnInitAsync()
    {
        stdMaster = await Http.GetJsonAsync<StudentMasters[]>("/api/StudentMasters/");
    }

明细表格绑定、隐藏/显示方法

在主表格切换图标单击事件中,我们调用下面的方法,并将 `studentID` 传递给它,以从 Web API 获取相应的 `student` 详细信息,并将结果绑定到明细表格。

protected async Task getStudentsDetails(int StudID)
    {
        if (studentIDs != StudID)
        {
            Imagename = "Images/expand.png";
            showDetailStatus = 1;
        }
        else
        {
            if (showDetailStatus == 0)
            {
                Imagename = "Images/expand.png";
                showDetailStatus = 1;
            }
            else
            {
                Imagename = "Images/toggle.png";
                showDetailStatus = 0;
            }

        }
        studentIDs = StudID;
        stdDetail = await Http.GetJsonAsync<StudentDetails[]>("/api/StudentDetails/" + 
                    Convert.ToInt32(StudID));
    }

排序方法

在每个列标题的排序图像单击时,我们调用此方法并将列名传递给该方法。在此方法中,根据列名,我们对 Web API 结果进行排序,并将结果绑定到 HTML 表格。我们还进行升序和降序的排序。

//Sorting
    protected async Task StudentSorting(string SortColumn)
    {
        stdMaster = await Http.GetJsonAsync<StudentMasters[]>("/api/StudentMasters/");

        if (ids == 0)
        {
            ImageSortname = "Images/sortDec.png";
            ids = 1;

            switch (SortColumn)
            {
                case "StdId":
                    stdMaster = stdMaster.OrderBy(x => x.StdId).ToArray() ;
                    break;
                case "StdName":
                    stdMaster = stdMaster.OrderBy(x => x.StdName).ToArray();
                    break;

                case "Email":
                    stdMaster = stdMaster.OrderBy(x => x.Email).ToArray();
                    break;
                case "Phone":
                    stdMaster = stdMaster.OrderBy(x => x.Phone).ToArray();
                    break;
                case "Address":
                    stdMaster = stdMaster.OrderBy(x => x.Address).ToArray();
                    break;

            }
        }
        else
        {
            ImageSortname = "Images/sortAsc.png";
            ids = 0;

            switch (SortColumn)
            {
                case "StdId":
                    stdMaster = stdMaster.OrderByDescending(x => x.StdId).ToArray();
                    break;
                case "StdName":
                    stdMaster = stdMaster.OrderByDescending(x => x.StdName).ToArray();
                    break;

                case "Email":
                    stdMaster = stdMaster.OrderByDescending(x => x.Email).ToArray();
                    break;
                case "Phone":
                    stdMaster = stdMaster.OrderByDescending(x => x.Phone).ToArray();
                    break;
                case "Address":
                    stdMaster = stdMaster.OrderByDescending(x => x.Address).ToArray();
                    break;
            }
        } 
    }

筛选方法

在每个列标题部分,我们添加了一个新行,用于对 HTML 表格进行筛选。在每个列筛选 `Textbox` 的更改事件中,我们传递 `Textbox` 值。我们调用一个通用的筛选方法 `studentFilteringList`,并在该方法中,我们传递筛选列的 `Textbox` 值和列名。

// For Filtering by Student Name
    void OnstdNameChanged(UIChangeEventArgs args)
    {
        string values = args.Value.ToString();
        studentFilteringList(values, "StudentName");
    }

    // For Filtering by Email
    void OnEmailChanged(UIChangeEventArgs args)
    {
        string values = args.Value.ToString();
        studentFilteringList(values, "Email");
    }

    // For Filtering by Phone
    void OnPhoneChanged(UIChangeEventArgs args)
    {
        string values = args.Value.ToString();
        studentFilteringList(values, "Phone");
    }

    // For Filtering by Adress
    void OnAddressChanged(UIChangeEventArgs args)
    {
        string values = args.Value.ToString();
        studentFilteringList(values, "Address");
    }

在这里,我们创建了一个名为 `studentFilteringList` 的通用函数,在该方法中,我们获取筛选列的 `Textbox` 值和列名。我们从 Web API 进行筛选,并将筛选结果绑定到 HTML 表格。

    //Filtering
    protected async Task studentFilteringList(String Value,string columnName)
    {
        stdMaster = await Http.GetJsonAsync<StudentMasters[]>("/api/StudentMasters/");

        if (Value.Trim().Length >0)
        {
            switch (columnName)
            {
                case "StudentName":
                    stdMaster = stdMaster.Where(x => x.StdName.Contains(Value)).ToArray();
                    break;

                case "Email":
                    stdMaster = stdMaster.Where(x => x.Email.Contains(Value)).ToArray();
                    break;
                case "Phone":
                    stdMaster = stdMaster.Where(x => x.Phone.Contains(Value)).ToArray();
                    break;
                case "Address":
                    stdMaster = stdMaster.Where(x => x.Address.Contains(Value)).ToArray();
                    break;
                default:
                    stdMaster = await Http.GetJsonAsync<StudentMasters[]>("/api/StudentMasters/");
                    break;
            }
        }
        else
        {
            stdMaster = await Http.GetJsonAsync<StudentMasters[]>("/api/StudentMasters/");
        }
    }

具有动态内容的 Razor 页面

首先,我们需要添加新的 Razor 视图页面。

添加 Razor 视图

要添加 Razor 视图页面,请右键单击 `Client` 项目中的 _Pages_ 文件夹。单击“添加”>>“新建项”。

选择 Razor View >> 输入您的页面名称。在这里,我们将其命名为 _Students.chtml_。

与我们之前的 Razor 视图页面一样,我们使用相同的逻辑来绑定主表格和明细表格。但在这里,我们不是直接绑定 HTML 来显示明细表格,而是使用 Blazor 动态内容来绑定明细表格的结果。我们已经看到了主数据绑定和切换按钮单击事件,现在对于此页面,我们将仅直接解释动态内容部分。

动态内容绑定 HTML 部分

与我们之前的页面一样,我们进行所有状态检查,最后绑定动态内容以显示明细 HTML 表格。我们使用 `@DynamicContent` 对象来绑定动态内容的结果。

@if (stdDetail != null)
            {
                @if (showDetailStatus == 1)
                {
                    @if (@StudentMasters.StdId == studentIDs)
                    {
                        <tr style="background-color:#6D7B8D ; color:honeydew ;border-style:dashed;
                         border-width:2px;border-color:#ECF3F4;">
                            <td colspan="6" align="center">
                                Student Details of  Student Id - <strong> @StudentMasters.StdId </strong> ,
                                Total @stdDetail.Length Grade details for this Student
                            </td>
                        </tr>
                        <tr>
                            <td></td>
                            <td colspan="5">
                                @DynamicContent
                            </td>
                        </tr>
                    }
                }
            }

动态内容绑定函数

我们使用 `RenderFragment` 对象来绑定动态内容结果。在我们的方法中使用 `RenderFragment` (Delegate) ,我们构建动态内容,并在运行时动态绑定结果。

private Microsoft.AspNetCore.Blazor.RenderFragment DynamicContent;

在明细 HTML 表格绑定的方法中,我们创建动态内容以在主表格内显示明细表格。在调用方法中,每次我们动态创建明细表格,并使用构建器在 `RenderFragment` 委托中绑定结果,我们动态创建表格并绑定结果。

stdDetail = await Http.GetJsonAsync<StudentDetails[]>
              ("/api/StudentDetails/" + Convert.ToInt32(StudID));

    DynamicContent = builder =>
    {

        var seq = 0;
        builder.OpenElement(seq, "table");
        builder.AddAttribute(seq, "style", "background-color:#ECF3F4;border-style:dashed;
        border-width:2px;border-color:#0A2464; padding:5px;width:100%;table-layout:fixed;");
// Heading
builder.OpenElement(++seq, "tr");
        builder.AddAttribute(++seq, "style", "height: 30px;border-style:inset;border-width:1px;
                             border-color:#6D7B8D; background-color:#336699 ; color:#FFFFFF ;");
        builder.OpenElement(++seq, "td");
        builder.AddContent(++seq, "Student Details");

        builder.CloseElement();

        builder.OpenElement(++seq, "td");
        builder.AddContent(++seq, "Major");

        builder.CloseElement();

        builder.OpenElement(++seq, "td");
        builder.AddContent(++seq, "Year");

        builder.CloseElement();

        builder.OpenElement(++seq, "td");
        builder.AddContent(++seq, "Term");

        builder.CloseElement();

        builder.OpenElement(++seq, "td");
        builder.AddContent(++seq, "Grade");

        builder.CloseElement();
        builder.CloseElement();
//Tbody

foreach (var stdDtls in stdDetail)
        {
            builder.OpenElement(++seq, "tr");
            builder.OpenElement(++seq, "td");
            builder.AddContent(++seq, stdDtls.StdDtlId);

            builder.CloseElement();

            builder.OpenElement(++seq, "td");
            builder.AddContent(++seq, stdDtls.Major);

            builder.CloseElement();

            builder.OpenElement(++seq, "td");
            builder.AddContent(++seq, stdDtls.Year);

            builder.CloseElement();

            builder.OpenElement(++seq, "td");
            builder.AddContent(++seq, stdDtls.Term);

            builder.CloseElement();

            builder.OpenElement(++seq, "td");
            builder.AddContent(++seq, stdDtls.Grade);

            builder.CloseElement();
            builder.CloseElement();
        }

        builder.CloseElement();
    };

构建并运行应用程序

关注点

在本文中,我们仅添加了一级表格层级。您可以将其扩展到创建多级 HTML 表格。请注意,在创建 `DBContext` 和设置连接字符串时,不要忘记添加您的 SQL 连接字符串。希望您喜欢这篇文章。在下一篇文章中,我们将看到更多关于 Blazor 的示例,使用 Blazor 确实非常棒!

历史

  • 2018年6月10日:BlazorMasterDetailGrid.zip
© . All rights reserved.