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下载地址

相关推荐
虚假程序设计4 小时前
pythonnet python图像 C# .NET图像 互转
开发语言·人工智能·python·opencv·c#·.net
我是苏苏5 小时前
Web开发:ABP框架3——入门级别的接口增删改查实现原理
c#·web开发·abp
Zhen (Evan) Wang5 小时前
.NET 6 API + Dapper + SQL Server 2014
数据库·c#·.net
VB.Net6 小时前
EmguCV学习笔记 VB.Net 12.3 OCR
opencv·计算机视觉·c#·ocr·图像·vb.net·emgucv
俊哥V6 小时前
[备忘]测算.net中对象所占用的内存
c#·.net·内存
闻缺陷则喜何志丹6 小时前
HObject复制耗时试用
c#·指针·halcon·key·图形图形·用时·非安全代码
friklogff6 小时前
【C#生态园】从数据分析到机器学习:掌握C#统计学库的核心功能
机器学习·数据分析·c#
我命由我123456 小时前
GPIO 理解(基本功能、模拟案例)
linux·运维·服务器·c语言·c++·嵌入式硬件·c#
VB.Net7 小时前
EmguCV学习笔记 C# 12.3 OCR
opencv·计算机视觉·c#·ocr·vb.net·emgucv
吃饭只吃七分饱12 小时前
arm开发板通信
arm开发·c#