开发分组式DataGridView Windows Form应用并对接指定JSON的ASP.NET Web API
Got it, let's build this grouped DataGridView WinForms app that connects to your ASP.NET Web API step by step. I'll break this down into manageable chunks so you can follow along easily.
- Create a new Windows Forms App (.NET Framework or .NET 6+/Core, either works) in Visual Studio.
- Drag a
DataGridViewcontrol from the Toolbox onto your form, and name itdgvProjectData. - Add a
Button(name itbtnLoadData) above the DataGridView to trigger data loading.
You need a C# class to convert the JSON response into usable objects. Right-click your project > Add > Class, name it ProjectContribution.cs:
public class ProjectContribution { public string Company { get; set; } public string ProjectName { get; set; } public string Developer { get; set; } public int Hour { get; set; } public int Overtime { get; set; } public string Contribution { get; set; } }
We'll use HttpClient to call your API. For .NET Framework, you may need to install the System.Net.Http and System.Text.Json packages via NuGet; for .NET 6+, these are included by default.
Double-click the btnLoadData button to add its click event handler, then paste this code:
using System.Net.Http; using System.Text.Json; using System.Windows.Forms; private async void btnLoadData_Click(object sender, EventArgs e) { try { btnLoadData.Enabled = false; using var httpClient = new HttpClient(); // Replace this URL with your actual API endpoint var response = await httpClient.GetAsync("https://your-api-base-url/api/project-contributions"); response.EnsureSuccessStatusCode(); // Throw error if request fails var jsonContent = await response.Content.ReadAsStringAsync(); var contributionList = JsonSerializer.Deserialize<List<ProjectContribution>>(jsonContent); // Pass the fetched data to our grouping logic BindGroupedData(contributionList); } catch (Exception ex) { MessageBox.Show($"Failed to load data: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { btnLoadData.Enabled = true; } }
WinForms DataGridView doesn't have built-in grouping, but we can manually add styled group header rows (grouped by Company > ProjectName) for a clean UI. Add this method to your form:
private void BindGroupedData(List<ProjectContribution> contributions) { // Clear existing data and columns dgvProjectData.Rows.Clear(); dgvProjectData.Columns.Clear(); // Define columns matching our model dgvProjectData.Columns.Add("Company", "Company"); dgvProjectData.Columns.Add("ProjectName", "Project Name"); dgvProjectData.Columns.Add("Developer", "Developer"); dgvProjectData.Columns.Add("Hour", "Total Hours"); dgvProjectData.Columns.Add("Overtime", "Overtime Hours"); dgvProjectData.Columns.Add("Contribution", "Contribution %"); // Format numeric columns for better readability dgvProjectData.Columns["Hour"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight; dgvProjectData.Columns["Overtime"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight; // Group data first by Company, then by ProjectName var groupedData = contributions .GroupBy(c => c.Company) .Select(companyGroup => new { CompanyName = companyGroup.Key, Projects = companyGroup.GroupBy(p => p.ProjectName) }); foreach (var company in groupedData) { // Add Company group header row var companyRowIndex = dgvProjectData.Rows.Add(); var companyRow = dgvProjectData.Rows[companyRowIndex]; companyRow.Cells["Company"].Value = $"📁 {company.CompanyName}"; companyRow.Cells["Company"].Style.BackColor = Color.LightGray; companyRow.Cells["Company"].Style.Font = new Font(dgvProjectData.Font, FontStyle.Bold); companyRow.ReadOnly = true; companyRow.Height = 25; foreach (var project in company.Projects) { // Add Project group header row var projectRowIndex = dgvProjectData.Rows.Add(); var projectRow = dgvProjectData.Rows[projectRowIndex]; projectRow.Cells["ProjectName"].Value = $" 📂 {project.Key}"; projectRow.Cells["ProjectName"].Style.BackColor = Color.LightBlue; projectRow.Cells["ProjectName"].Style.Font = new Font(dgvProjectData.Font, FontStyle.Italic); projectRow.ReadOnly = true; projectRow.Height = 22; // Add individual developer rows under the project foreach (var devContribution in project) { dgvProjectData.Rows.Add( string.Empty, // Leave Company cell empty under group string.Empty, // Leave ProjectName cell empty under group devContribution.Developer, devContribution.Hour, devContribution.Overtime, devContribution.Contribution ); } } } // Auto-size columns to fit content dgvProjectData.AutoResizeColumns(); }
- Set
dgvProjectData.RowHeadersVisible = false;to clean up the UI (optional but recommended) - Make column headers bold with:
dgvProjectData.ColumnHeadersDefaultCellStyle.Font = new Font(dgvProjectData.Font, FontStyle.Bold); - Enable column sorting by setting each column's
SortModetoDataGridViewColumnSortMode.Automatic(via Properties window or code)
- Replace the API URL in
btnLoadData_Clickwith your actual endpoint. - Run the app, click the "Load Data" button. You'll see data grouped by Company first, then Project Name, with distinct styled headers for each group.
内容的提问来源于stack exchange,提问作者Sachith Wickramaarachchi

