开源 C# 快速开发(三)复杂控件

文章的目的为了记录使用C# 开发学习的经历。开发流程和要点有些记忆模糊,赶紧记录,防止忘记。

相关链接:

开源 C# 快速开发(一)基础知识

开源 C# 快速开发(二)基础控件

开源 C# 快速开发(三)复杂控件

推荐链接:

开源 C# .net mvc 开发(一)WEB搭建_c#部署web程序-CSDN博客

开源 C# .net mvc 开发(二)网站快速搭建_c#网站开发-CSDN博客

开源 C# .net mvc 开发(三)WEB内外网访问-CSDN博客

开源 C# .net mvc 开发(四)工程结构、页面提交以及显示-CSDN博客

开源 C# .net mvc 开发(五)常用代码快速开发_c# mvc开发-CSDN博客

开源 C# .net mvc 开发(六)发送邮件、定时以及CMD编程-CSDN博客

开源 C# .net mvc 开发(七)动态图片、动态表格和json数据生成-CSDN博客

开源 C# .net mvc 开发(八)IIS Express轻量化Web服务器的配置和使用-CSDN博客

开源 C# .net mvc 开发(九)websocket--服务器与客户端的实时通信-CSDN博客

本章节主要内容是:创建了一个窗体应用程序,用于演示三种常见的复杂控件。列表控件:ListBox、ListView和DataGridView的功能和用法。

1.源码分析

2.所有源码

3.显示效果

一、源码分析

这个源码并没有采用界面设计器来进行ListBox、ListView和DataGridView这3中控件的拖取设计,而是采用了代码直接添加的办法。

  1. 界面布局

使用TabControl组织三个不同的列表控件

每个控件位于独立的TabPage中

底部有一个多行文本框用于显示选择信息

1) TabControl创建和配置

复制代码
TabControl tabControl = new TabControl();
tabControl.Dock = DockStyle.Top;  // 停靠在顶部
tabControl.Height = 350;          // 固定高度350像素

2)三个TabPage创建

复制代码
TabPage tabListBox = new TabPage("ListBox");
TabPage tabListView = new TabPage("ListView"); 
TabPage tabDataGridView = new TabPage("DataGridView");
  1. 控件配置特点

ListBox:

支持多选模式(MultiExtended)

包含9个项目,分为水果、蔬菜、饮料三组

复制代码
ListBox listBox = new ListBox();
listBox.Dock = DockStyle.Fill;                    // 填充整个TabPage
listBox.SelectionMode = SelectionMode.MultiExtended;  // 支持扩展多选
// 使用lambda表达式注册选择改变事件
listBox.SelectedIndexChanged += (s, e) => ShowSelectionInfo(listBox, textBoxResult, "ListBox");

ListView:

使用详细信息视图(View.Details)

启用整行选择和网格线

包含4列:序号、名称、类别、价格

复制代码
ListView listView = new ListView();
listView.Dock = DockStyle.Fill;
listView.View = View.Details;      // 详细信息视图
listView.FullRowSelect = true;     // 整行选择
listView.GridLines = true;         // 显示网格线
listView.MultiSelect = true;       // 支持多选
listView.SelectedIndexChanged += (s, e) => ShowSelectionInfo(listView, textBoxResult, "ListView");

DataGridView:

绑定到DataTable数据源

设置为只读和整行选择模式

包含5列:ID、产品名称、分类、库存、状态

复制代码
DataGridView dataGridView = new DataGridView();
dataGridView.Dock = DockStyle.Fill;
dataGridView.ReadOnly = true;      // 只读模式
dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;  // 整行选择
dataGridView.MultiSelect = true;   // 支持多选
dataGridView.SelectionChanged += (s, e) => ShowSelectionInfo(dataGridView, textBoxResult, "DataGridView");
  1. 数据填充逻辑

每个控件都填充了3组数据,每组3个项目:

ListBox: 简单的文本项目

PopulateListBox()函数

复制代码
private void PopulateListBox()
{
    string[] groups = { "水果", "蔬菜", "饮料" };  // 定义三组数据
    
    // 双层循环创建9个项目
    for (int i = 0; i < 3; i++)        // 组循环
    {
        for (int j = 0; j < 3; j++)    // 项目循环
        {
            string itemName = $"{groups[i]} - 项目{j + 1}";  // 格式化项目名称
            listBox.Items.Add(itemName);  // 添加到ListBox
        }
    }
}

ListView: 结构化数据(价格信息)

PopulateListView()函数

复制代码
private void PopulateListView()
{
    // 创建列头
    listView.Columns.Add("序号", 60);   // 列名和宽度
    listView.Columns.Add("名称", 100);
    listView.Columns.Add("类别", 80);
    listView.Columns.Add("价格", 80);
    
    string[] categories = { "电子产品", "图书", "服装" };
    string[] prices = { "¥2999", "¥59", "¥199" };
    
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            ListViewItem item = new ListViewItem((i * 3 + j + 1).ToString());  // 第一列
            item.SubItems.Add($"{categories[i]}型号{j + 1}");  // 第二列
            item.SubItems.Add(categories[i]);                  // 第三列  
            item.SubItems.Add(prices[i]);                      // 第四列
            listView.Items.Add(item);
        }
    }
}

DataGridView: 更复杂的数据结构(包含数字和状态)

PopulateDataGridView()函数

复制代码
private void PopulateDataGridView()
{
    // 创建DataTable结构
    DataTable table = new DataTable();
    table.Columns.Add("ID", typeof(int));
    table.Columns.Add("产品名称", typeof(string));
    table.Columns.Add("分类", typeof(string));
    table.Columns.Add("库存", typeof(int));
    table.Columns.Add("状态", typeof(string));
    
    string[] statuses = { "有库存", "缺货", "预售" };
    string[] categories = { "手机", "电脑", "平板" };
    
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            table.Rows.Add(
                i * 3 + j + 1,              // ID
                $"{categories[i]} {j + 1}", // 产品名称
                categories[i],              // 分类
                (j + 1) * 10,               // 库存(10,20,30)
                statuses[j]                 // 状态
            );
        }
    }
    
    dataGridView.DataSource = table;  // 绑定数据源
    
    // 设置列宽
    dataGridView.Columns[0].Width = 50;
    dataGridView.Columns[1].Width = 120;
    dataGridView.Columns[2].Width = 80;
    dataGridView.Columns[3].Width = 60;
    dataGridView.Columns[4].Width = 80;
}
  1. 事件处理

使用统一的ShowSelectionInfo方法处理所有控件的选择变化事件,显示:

选中项目的详细信息

选中项目的总数

不同类型控件的特定属性

复制代码
       private void ShowSelectionInfo(object sender, TextBox textBox, string controlName)
        {
            textBox.Clear();
            textBox.AppendText($"{controlName} 选择信息:\r\n");
            textBox.AppendText("".PadRight(40, '=') + "\r\n");

            if (sender is ListBox lb)
            {
                if (lb.SelectedItems.Count == 0)
                {
                    textBox.AppendText("未选择任何项目\r\n");
                    return;
                }

                foreach (var item in lb.SelectedItems)
                {
                    int index = lb.Items.IndexOf(item);
                    textBox.AppendText($"序号: {index}, 名称: {item}\r\n");
                }
                textBox.AppendText($"总计选择: {lb.SelectedItems.Count} 个项目\r\n");
            }
            else if (sender is ListView lv)
            {
                if (lv.SelectedItems.Count == 0)
                {
                    textBox.AppendText("未选择任何行\r\n");
                    return;
                }

                foreach (ListViewItem item in lv.SelectedItems)
                {
                    textBox.AppendText($"序号: {item.Index}, ");
                    textBox.AppendText($"名称: {item.SubItems[1].Text}, ");
                    textBox.AppendText($"类别: {item.SubItems[2].Text}, ");
                    textBox.AppendText($"价格: {item.SubItems[3].Text}\r\n");
                }
                textBox.AppendText($"总计选择: {lv.SelectedItems.Count} 行\r\n");
            }
            else if (sender is DataGridView dgv)
            {
                if (dgv.SelectedRows.Count == 0)
                {
                    textBox.AppendText("未选择任何行\r\n");
                    return;
                }

                foreach (DataGridViewRow row in dgv.SelectedRows)
                {
                    if (!row.IsNewRow)
                    {
                        textBox.AppendText($"行号: {row.Index}, ");
                        textBox.AppendText($"ID: {row.Cells["ID"].Value}, ");
                        textBox.AppendText($"产品: {row.Cells["产品名称"].Value}, ");
                        textBox.AppendText($"库存: {row.Cells["库存"].Value}, ");
                        textBox.AppendText($"状态: {row.Cells["状态"].Value}\r\n");
                    }
                }
                textBox.AppendText($"总计选择: {dgv.SelectedRows.Count} 行\r\n");
            }
        }

二、所有源码

Form1.cs源码

复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace _2_specialctrl
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            InitializeControls();
            PopulateListBox();
            PopulateListView();
            PopulateDataGridView();

        }
        private void InitializeControls()
        {
            // 设置窗体
            this.Text = "List控件演示 - ListBox, ListView, DataGridView";
            this.Size = new Size(800, 600);
            this.StartPosition = FormStartPosition.CenterScreen;

            // 创建TabControl来组织三个控件
            TabControl tabControl = new TabControl();
            tabControl.Dock = DockStyle.Top;
            tabControl.Height = 350;

            // 创建三个TabPage
            TabPage tabListBox = new TabPage("ListBox");
            TabPage tabListView = new TabPage("ListView");
            TabPage tabDataGridView = new TabPage("DataGridView");

            // 创建显示结果的TextBox
            TextBox textBoxResult = new TextBox();
            textBoxResult.Dock = DockStyle.Bottom;
            textBoxResult.Height = 100;
            textBoxResult.Multiline = true;
            textBoxResult.ScrollBars = ScrollBars.Vertical;
            textBoxResult.ReadOnly = true;

            // 将TabPage添加到TabControl
            tabControl.TabPages.Add(tabListBox);
            tabControl.TabPages.Add(tabListView);
            tabControl.TabPages.Add(tabDataGridView);

            // 创建并配置ListBox
            ListBox listBox = new ListBox();
            listBox.Dock = DockStyle.Fill;
            listBox.SelectionMode = SelectionMode.MultiExtended;
            listBox.SelectedIndexChanged += (s, e) => ShowSelectionInfo(listBox, textBoxResult, "ListBox");

            // 创建并配置ListView
            ListView listView = new ListView();
            listView.Dock = DockStyle.Fill;
            listView.View = View.Details;
            listView.FullRowSelect = true;
            listView.GridLines = true;
            listView.MultiSelect = true;
            listView.SelectedIndexChanged += (s, e) => ShowSelectionInfo(listView, textBoxResult, "ListView");

            // 创建并配置DataGridView
            DataGridView dataGridView = new DataGridView();
            dataGridView.Dock = DockStyle.Fill;
            dataGridView.ReadOnly = true;
            dataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            dataGridView.MultiSelect = true;
            dataGridView.SelectionChanged += (s, e) => ShowSelectionInfo(dataGridView, textBoxResult, "DataGridView");

            // 将控件添加到各自的TabPage
            tabListBox.Controls.Add(listBox);
            tabListView.Controls.Add(listView);
            tabDataGridView.Controls.Add(dataGridView);

            // 添加到窗体
            this.Controls.Add(tabControl);
            this.Controls.Add(textBoxResult);

            // 存储控件引用以便后续使用
            this.listBox = listBox;
            this.listView = listView;
            this.dataGridView = dataGridView;
        }

        private void PopulateListBox()
        {
            // 为ListBox添加9个项目(3组,每组3个)
            string[] groups = { "水果", "蔬菜", "饮料" };

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    string itemName = $"{groups[i]} - 项目{j + 1}";
                    listBox.Items.Add(itemName);
                }
            }
        }

        private void PopulateListView()
        {
            // 为ListView创建列
            listView.Columns.Add("序号", 60);
            listView.Columns.Add("名称", 100);
            listView.Columns.Add("类别", 80);
            listView.Columns.Add("价格", 80);

            // 添加3行数据
            string[] categories = { "电子产品", "图书", "服装" };
            string[] prices = { "¥2999", "¥59", "¥199" };

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    ListViewItem item = new ListViewItem((i * 3 + j + 1).ToString());
                    item.SubItems.Add($"{categories[i]}型号{j + 1}");
                    item.SubItems.Add(categories[i]);
                    item.SubItems.Add(prices[i]);
                    listView.Items.Add(item);
                }
            }
        }

        private void PopulateDataGridView()
        {
            // 创建DataTable作为数据源
            DataTable table = new DataTable();
            table.Columns.Add("ID", typeof(int));
            table.Columns.Add("产品名称", typeof(string));
            table.Columns.Add("分类", typeof(string));
            table.Columns.Add("库存", typeof(int));
            table.Columns.Add("状态", typeof(string));

            // 添加3行数据
            string[] statuses = { "有库存", "缺货", "预售" };
            string[] categories = { "手机", "电脑", "平板" };

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    table.Rows.Add(
                        i * 3 + j + 1,
                        $"{categories[i]} {j + 1}",
                        categories[i],
                        (j + 1) * 10,
                        statuses[j]
                    );
                }
            }

            dataGridView.DataSource = table;

            // 设置列宽
            dataGridView.Columns[0].Width = 50;
            dataGridView.Columns[1].Width = 120;
            dataGridView.Columns[2].Width = 80;
            dataGridView.Columns[3].Width = 60;
            dataGridView.Columns[4].Width = 80;
        }

        private void ShowSelectionInfo(object sender, TextBox textBox, string controlName)
        {
            textBox.Clear();
            textBox.AppendText($"{controlName} 选择信息:\r\n");
            textBox.AppendText("".PadRight(40, '=') + "\r\n");

            if (sender is ListBox lb)
            {
                if (lb.SelectedItems.Count == 0)
                {
                    textBox.AppendText("未选择任何项目\r\n");
                    return;
                }

                foreach (var item in lb.SelectedItems)
                {
                    int index = lb.Items.IndexOf(item);
                    textBox.AppendText($"序号: {index}, 名称: {item}\r\n");
                }
                textBox.AppendText($"总计选择: {lb.SelectedItems.Count} 个项目\r\n");
            }
            else if (sender is ListView lv)
            {
                if (lv.SelectedItems.Count == 0)
                {
                    textBox.AppendText("未选择任何行\r\n");
                    return;
                }

                foreach (ListViewItem item in lv.SelectedItems)
                {
                    textBox.AppendText($"序号: {item.Index}, ");
                    textBox.AppendText($"名称: {item.SubItems[1].Text}, ");
                    textBox.AppendText($"类别: {item.SubItems[2].Text}, ");
                    textBox.AppendText($"价格: {item.SubItems[3].Text}\r\n");
                }
                textBox.AppendText($"总计选择: {lv.SelectedItems.Count} 行\r\n");
            }
            else if (sender is DataGridView dgv)
            {
                if (dgv.SelectedRows.Count == 0)
                {
                    textBox.AppendText("未选择任何行\r\n");
                    return;
                }

                foreach (DataGridViewRow row in dgv.SelectedRows)
                {
                    if (!row.IsNewRow)
                    {
                        textBox.AppendText($"行号: {row.Index}, ");
                        textBox.AppendText($"ID: {row.Cells["ID"].Value}, ");
                        textBox.AppendText($"产品: {row.Cells["产品名称"].Value}, ");
                        textBox.AppendText($"库存: {row.Cells["库存"].Value}, ");
                        textBox.AppendText($"状态: {row.Cells["状态"].Value}\r\n");
                    }
                }
                textBox.AppendText($"总计选择: {dgv.SelectedRows.Count} 行\r\n");
            }
        }

        // 控件引用
        private ListBox listBox;
        private ListView listView;
        private DataGridView dataGridView;


    }
}

三、显示效果

listbox效果

listview效果

dataGridView效果

相关推荐
郝学胜-神的一滴2 小时前
深入理解前端 Axios 框架:特性、使用场景与最佳实践
开发语言·前端·程序人生·软件工程
jf加菲猫2 小时前
条款11:优先选用删除函数,而非private未定义函数
开发语言·c++
歪歪1002 小时前
什么是TCP/UDP/HTTP?
开发语言·网络·网络协议·tcp/ip·http·udp
WangMing_X2 小时前
C#上位机软件:2.1 .NET项目解决方案的作用
开发语言·c#
Pocker_Spades_A3 小时前
Python快速入门专业版(四十六):Python类的方法:实例方法、类方法、静态方法与魔术方法
开发语言·python
零雲3 小时前
java面试:可以讲一讲sychronized和ReentrantLock的异同点吗
java·开发语言·面试
yubo05093 小时前
YOLO系列——实时屏幕检测
开发语言·windows·python
怀旧,3 小时前
【C++】23. C++11(上)
开发语言·c++
l1t3 小时前
使用DeepSeek辅助测试一个rust编写的postgresql协议工具包convergence
开发语言·postgresql·rust·协议·datafusion