Winform ListView 嵌入组合框、布尔、图片等复杂控件

一、Winform ListView 显示复杂控件示例

  • 以下展示了两种实现思路方案。
  • 最后修改日期 2024-05 surfsky

1.1 方案一:ListView 结合组合框进行模拟编辑

基本思路

  • 在界面上放置一个lisview和一个combobox,combobox平时是隐藏的。
  • 点击listview,在点击位置的单元格上显示这个combobox
  • combobbox数据变更后,更新到listview

核心代码如:

csharp 复制代码
    public partial class Form1 : Form
    {
        ListViewSubItem _cell;  // 被选中的单元格

        public Form1()
        {
            InitializeComponent();
            InitData();
        }

        void InitData()
        {
            // combobox 
            comboBox1.Visible = false;
            this.comboBox1.Items.Add("科比");
            this.comboBox1.Items.Add("姚明");
            this.comboBox1.Items.Add("杜兰特");
            this.comboBox1.Items.Add("邓肯");

            // listview
            listView1.Columns.Add("第一列");
            listView1.Columns.Add("第二列");
            listView1.Columns.Add("第三列");

            var item = new ListViewItem(1.ToString());
            item.SubItems.Add("姚明");
            item.SubItems.Add("科比");
            listView1.Items.Add(item);

            item = new ListViewItem(2.ToString());
            item.SubItems.Add("邓肯");
            item.SubItems.Add("杜兰特");
            listView1.Items.Add(item);
        }

        // ListView 点击后在点击单位格位置处显示控件
        private void lv_MouseUp(object sender, MouseEventArgs e)
        {
            // 将控件定位到点击单元格中
            var lvi = this.listView1.GetItemAt(e.X, e.Y);
            if (lvi != null)
            {
                _cell = lvi.GetSubItemAt(e.X, e.Y);
                var n = lvi.SubItems.IndexOf(_cell);
                if (_cell != null && n>0)
                {
                    var rect = _cell.Bounds;
                    rect.Y += 5;
                    this.comboBox1.Visible = true;
                    this.comboBox1.Bounds = rect;
                    this.comboBox1.Text = _cell.Text;
                    this.comboBox1.BringToFront();
                    //this.comboBox1.Focus();
                    return;
                }
            }
            this.comboBox1.Visible = false;
        }

        // 组合框数据变更后,将数据更新到单元格
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (_cell != null)
            {
                _cell.Text = comboBox1.Text;
            }
        }
    }

效果如:

1.2 方案二:自定义 ListView 和各种列

功能

  • 嵌入下拉框列
  • 嵌入色彩列
  • 嵌入数字编辑列
  • 嵌入布尔值列
  • 嵌入图片列
  • 点击标题列排序
  • 行选择

使用代码

csharp 复制代码
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
            InitListView();
        }

        public void InitListView()
        {
            this.lv.Columns.Add(new BaseColumnHeader("序号", 50));
            this.lv.Columns.Add(new BaseColumnHeader("可见", 50));
            this.lv.Columns.Add(new BaseColumnHeader("颜色", 60));
            this.lv.Columns.Add(new BaseColumnHeader("数值", 150));
            this.lv.Columns.Add(new BoolColumnHeader("布尔值", Resources.BulletTick, Resources.BulletCross, 100));
            this.lv.Columns.Add(new BaseColumnHeader("图片", 200));

            var r = new Random();
            for (int i = 0; i < 10; i++)
            {
                lv.BeginUpdate();
                var b = r.Next(100) % 2 == 0 ? true : false;
                var item = new ListViewItemBase(i.ToString());
                var visibleCell = new ListViewControlSubItem();
                var colorCell = new ListViewControlSubItem();
                var numCell = new ListViewControlSubItem();
                var boolCell = new ListViewBoolSubItem(b);
                var imageCell = new ListViewImageSubItem(Resources.Cart);

                // combox
                var cmbVisible = new ComboBox();
                cmbVisible.Items.Add("是");
                cmbVisible.Items.Add("否");
                cmbVisible.SelectedIndex = 0;
                //cmbVisible.Focus();

                // color label
                var label = new Label();
                label.BackColor = Color.Green;
                label.Text = "";
                label.BorderStyle = BorderStyle.FixedSingle;
                label.MouseClick += new MouseEventHandler(bt_MouseClick);
                
                // number box
                var num = new NumericUpDown();
                num.Margin = new Padding(0);
                num.Minimum = new decimal(-999999999.0);
                num.Maximum = new decimal(999999999.0);
                num.Value = new decimal(i * 10);
                num.DecimalPlaces = 2;

                // controls
                lv.AddControlToSubItem(visibleCell, cmbVisible);
                lv.AddControlToSubItem(colorCell, label);
                lv.AddControlToSubItem(numCell, num);
                item.SubItems.Add(visibleCell);
                item.SubItems.Add(colorCell);
                item.SubItems.Add(numCell);
                item.SubItems.Add(boolCell);
                item.SubItems.Add(imageCell);
                lv.Items.Add(item);
                lv.EndUpdate();
            }           
        }

        // color box
        void bt_MouseClick(object sender, MouseEventArgs e)
        {
            Label lb = (Label)sender;
            colorDialog1.Color = lb.BackColor;
            if (colorDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                lb.BackColor = colorDialog1.Color;
            }
        }


        // get selected item values
        private void button1_Click(object sender, EventArgs e)
        {
            if (lv.SelectedIndices.Count == 0)
            {
                MessageBox.Show("没有选择");
                return;
            }

            for (int j = 0; j < lv.SelectedIndices.Count; j++)
            {
                // item
                int i = lv.SelectedIndices[j];
                var itemName = lv.Items[i] as ListViewItemBase;
                var itemVisible = itemName.SubItems[1] as ListViewControlSubItem;
                var itemColor   = itemName.SubItems[2] as ListViewControlSubItem;
                var itemValue   = itemName.SubItems[3] as ListViewControlSubItem;

                // controls
                ComboBox cmbVisible = itemVisible.Control as ComboBox;
                Label lb = itemColor.Control as Label;
                var num = itemValue.Control as NumericUpDown;

                // values
                string name = itemName.Text;
                Color color = lb.BackColor;
                string visible = cmbVisible.Text;
                double value = Convert.ToDouble((num).Value);
                MessageBox.Show(string.Format("{0},{1},{2},{3}", name, color.ToString(), visible, value));
            }
        }

        private void lv_SelectedIndexChanged(object sender, EventArgs e)
        {
            var ids = lv.SelectedIndices;
        }
    }

效果如:

二、代码下载

CSDN下载地址

相关推荐
kimloner2 小时前
开源一个 376KB 的 Windows 桌面小工具:便签 + 截图标注 + OCR + 待办提醒(C# / WinForms)
windows·开源·c#·ocr·winforms
阿松爱学习3 小时前
【Unity开发】Aspose.PDF的使用
unity·pdf·c#
半亩码田3 小时前
C#转Python第4.8篇:正则表达式:Python re 模块 vs C# System.Text.RegularExpressions
python·正则表达式·c#
FPGA小徐4 小时前
【一生一芯 / PA】异常响应机制:RISC-V 中 ecall → mtvec → mret 的完整代
开发语言·数据库·c#
淡海水5 小时前
02-04-原理篇-GC Roots与对象图遍历
算法·unity·c#·图·gc·遍历·roots
胖纸不争9 小时前
嫌桌面 Agent 太重,我“自己”写了一个
ai·c#·net core
当青春邂逅吉米多维奇13 小时前
C#图解教程(第5版) 同步方法
开发语言·c#
波力海苔夹心脆67513 小时前
C# 机器视觉实战:单相机引导机械手精准贴合,从拍照、偏差计算(平移+旋转)到坐标补偿全解
开发语言·经验分享·数码相机·c#·视觉检测·.net
Behavior15 小时前
国内下载使用 Unity 6000 踩坑点总结
c#·unity3d·游戏开发
czhc114007566316 小时前
一张图从哪来,一个判断往哪走
c#