如何在C# Windows Forms应用中展示自定义数据报表
Alright, let's walk through how to build this exact functionality for your C# Windows Forms app. I'll break it down into manageable steps so you can implement it easily:
First, let's create a simple class to represent each row of your data—this makes manipulating and grouping the data far cleaner than working directly with a raw DataTable:
public class DataEntry { public int ID { get; set; } public string Name { get; set; } public int Value { get; set; } public string Day { get; set; } public int Stage { get; set; } public DateTime CreationDate { get; set; } }
Next, we'll load your data (whether from a database or hardcoded for testing) into a list of this class, then group it by day—and crucially, sort those groups in Monday-to-Sunday order (since default string sorting would put "Fri" before "Mon", which isn't what we want):
// Replace this with your actual data loading logic (e.g., from SQL) var dataEntries = new List<DataEntry> { new DataEntry { ID = 1, Name = "1st", Value = 20, Day = "Mon", Stage = 1 }, new DataEntry { ID = 2, Name = "2nd", Value = 30, Day = "Mon", Stage = 2 }, new DataEntry { ID = 3, Name = "3rd", Value = 15, Day = "Tue", Stage = 1 }, new DataEntry { ID = 4, Name = "4th", Value = 10, Day = "Wed", Stage = 3 }, new DataEntry { ID = 5, Name = "5th", Value = 25, Day = "Thu", Stage = 4 }, new DataEntry { ID = 6, Name = "6th", Value = 15, Day = "Fri", Stage = 1 }, new DataEntry { ID = 7, Name = "7th", Value = 10, Day = "Fri", Stage = 2 }, new DataEntry { ID = 8, Name = "8th", Value = 30, Day = "Sat", Stage = 3 }, new DataEntry { ID = 9, Name = "9th", Value = 20, Day = "Sat", Stage = 1 }, new DataEntry { ID = 10, Name = "10th", Value = 20, Day = "Sun", Stage = 4 } }; // Define the exact order we want days to appear in var dayPriority = new List<string> { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; // Group entries by day and sort the groups to match our desired order var groupedData = dataEntries .GroupBy(entry => entry.Day) .OrderBy(group => dayPriority.IndexOf(group.Key)) .ToList();
We'll use a dictionary to link each stage value to a unique background color—you can tweak these colors to match your app's design:
var stageColorMap = new Dictionary<int, Color> { { 1, Color.LightSkyBlue }, { 2, Color.PaleGreen }, { 3, Color.LightCoral }, { 4, Color.LemonChiffon } };
For this, we'll use a FlowLayoutPanel (add one to your form and name it flowLayoutPanelResults) to hold each day's group. Each group will be a GroupBox containing individual labels for each data entry (with the correct background color):
Add this method to your form code:
private void PopulateResultsUI() { flowLayoutPanelResults.Controls.Clear(); // Clear any existing content foreach (var dayGroup in groupedData) { // Create a GroupBox for the day var dayGroupBox = new GroupBox(); dayGroupBox.Text = $"{dayGroup.Key}:"; dayGroupBox.AutoSize = true; dayGroupBox.Margin = new Padding(8); // Inner flow panel to arrange the entry labels horizontally var innerFlowPanel = new FlowLayoutPanel(); innerFlowPanel.AutoSize = true; innerFlowPanel.Dock = DockStyle.Fill; innerFlowPanel.Padding = new Padding(6); foreach (var entry in dayGroup) { // Create a label for each data entry var entryLabel = new Label(); entryLabel.Text = $"{entry.Name}-{entry.Value}$"; entryLabel.Padding = new Padding(4); entryLabel.Margin = new Padding(4); entryLabel.BorderStyle = BorderStyle.FixedSingle; // Optional: adds a clean border // Set background color based on stage (fallback to white if stage isn't mapped) entryLabel.BackColor = stageColorMap.TryGetValue(entry.Stage, out var color) ? color : Color.White; innerFlowPanel.Controls.Add(entryLabel); } dayGroupBox.Controls.Add(innerFlowPanel); flowLayoutPanelResults.Controls.Add(dayGroupBox); } }
Then call this method when your form loads:
private void MainForm_Load(object sender, EventArgs e) { PopulateResultsUI(); }
- If your data comes from a database, replace the hardcoded
dataEntrieslist with logic to load rows intoDataEntryobjects (useSqlDataReaderor Entity Framework for this). - To make color changes easier later, move the
stageColorMapto a configuration file instead of hardcoding it. - For large datasets, load the data asynchronously to keep your UI responsive while fetching records.
内容的提问来源于stack exchange,提问作者Azeem112

