在WinForms中将按钮添加到Listview中

winforms listview button

79612 观看

11回复

14303 作者的声誉

有没有办法在WinForms应用程序中的ListView内向单元格添加按钮控件?

作者: Adam Tegen 的来源 发布者: 2009 年 1 月 18 日

回应 11


1

7596 作者的声誉

也许这可能是有意义的?

http://www.codeproject.com/KB/list/extendedlistviews.aspx

作者: Dan Byström 发布者: 2009 年 2 月 10 日

14

10553 作者的声誉

ListView本身(或ListViewItem)不能作为任何类型的容器运行,因此无法直接添加控件,但它是可行的。我已经使用这个扩展的ListView取得了很大的成功:在ListView中嵌入控件

作者: Ryan Farley 发布者: 2009 年 3 月 9 日

1

443 作者的声誉

不,标准Windows窗体ListView不支持嵌入式控件。您可以尝试构建自己的自定义控件,也可以使用http://www.codeproject.com/KB/list/EXListView.aspx之类的东西。

作者: walterbing1 发布者: 2010 年 7 月 30 日

0

293 作者的声誉

不,是的,ListView本身不支持此类功能,但您可以在其上创建一个按钮,以便它作为列表视图的组成部分显示给用户。(我想这也是上面提到的ExtendedListView所做的)。

作者: Marzena 发布者: 2010 年 12 月 2 日

0

8017 作者的声誉

我之前不小心碰到了一个讨论,希望得到这个帮助:http//social.msdn.microsoft.com/Forums/en-US/winforms/thread/ee232cc4-68c5-4ed3-9ea7-d4d999956504/

作者: Hoàng Long 发布者: 2010 年 12 月 23 日

1

3929 作者的声誉

也许值得一提的是,列表视图控件可能在WPF中设计为带有ListViewItems中按钮的usercontrol / custom控件,然后在ElementHost控件中的WinForms应用程序中使用此控件。

作者: Andrei Pana 发布者: 2010 年 12 月 23 日

17

103836 作者的声誉

这是ListViewExtender您可以重用的类的代码。它不是派生类ListView,基本上你只是声明一个特定的列显示为按钮而不是文本。按钮的文本是subItem的文本。

它允许没有问题的大型列表视图,不使用p / invoke,也可以使用水平滚动条(这里提出的一些代码作为答案,或者对于大量项目来说非常慢)。请注意,它需要扩展ListView FullRowSelect设置为true和查看类型设置为Details

这是一个使用它的示例代码:

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent(); // you need to add a listView named listView1 with the designer
            listView1.FullRowSelect = true;
            ListViewExtender extender = new ListViewExtender(listView1);
            // extend 2nd column
            ListViewButtonColumn buttonAction = new ListViewButtonColumn(1);
            buttonAction.Click += OnButtonActionClick;
            buttonAction.FixedWidth = true;

            extender.AddColumn(buttonAction);

            for (int i = 0; i < 10000; i++)
            {
                ListViewItem item = listView1.Items.Add("item" + i);
                item.SubItems.Add("button " + i);
            }
        }

        private void OnButtonActionClick(object sender, ListViewColumnMouseEventArgs e)
        {
            MessageBox.Show(this, @"you clicked " + e.SubItem.Text);
        }
    }
}

这是ListViewExtender代码和相关类:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;

namespace WindowsFormsApplication1
{
    public class ListViewExtender : IDisposable
    {
        private readonly Dictionary<int, ListViewColumn> _columns = new Dictionary<int, ListViewColumn>();

        public ListViewExtender(ListView listView)
        {
            if (listView == null)
                throw new ArgumentNullException("listView");

            if (listView.View != View.Details)
                throw new ArgumentException(null, "listView");

            ListView = listView;
            ListView.OwnerDraw = true;
            ListView.DrawItem += OnDrawItem;
            ListView.DrawSubItem += OnDrawSubItem;
            ListView.DrawColumnHeader += OnDrawColumnHeader;
            ListView.MouseMove += OnMouseMove;
            ListView.MouseClick += OnMouseClick;

            Font = new Font(ListView.Font.FontFamily, ListView.Font.Size - 2);
        }

        public virtual Font Font { get; private set; }
        public ListView ListView { get; private set; }

        protected virtual void OnMouseClick(object sender, MouseEventArgs e)
        {
            ListViewItem item;
            ListViewItem.ListViewSubItem sub;
            ListViewColumn column = GetColumnAt(e.X, e.Y, out item, out sub);
            if (column != null)
            {
                column.MouseClick(e, item, sub);
            }
        }

        public ListViewColumn GetColumnAt(int x, int y, out ListViewItem item, out ListViewItem.ListViewSubItem subItem)
        {
            subItem = null;
            item = ListView.GetItemAt(x, y);
            if (item == null)
                return null;

            subItem = item.GetSubItemAt(x, y);
            if (subItem == null)
                return null;

            for (int i = 0; i < item.SubItems.Count; i++)
            {
                if (item.SubItems[i] == subItem)
                    return GetColumn(i);
            }
            return null;
        }

        protected virtual void OnMouseMove(object sender, MouseEventArgs e)
        {
            ListViewItem item;
            ListViewItem.ListViewSubItem sub;
            ListViewColumn column = GetColumnAt(e.X, e.Y, out item, out sub);
            if (column != null)
            {
                column.Invalidate(item, sub);
                return;
            }
            if (item != null)
            {
                ListView.Invalidate(item.Bounds);
            }
        }

        protected virtual void OnDrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
        {
            e.DrawDefault = true;
        }

        protected virtual void OnDrawSubItem(object sender, DrawListViewSubItemEventArgs e)
        {
            ListViewColumn column = GetColumn(e.ColumnIndex);
            if (column == null)
            {
                e.DrawDefault = true;
                return;
            }

            column.Draw(e);
        }

        protected virtual void OnDrawItem(object sender, DrawListViewItemEventArgs e)
        {
            // do nothing
        }

        public void AddColumn(ListViewColumn column)
        {
            if (column == null)
                throw new ArgumentNullException("column");

            column.Extender = this;
            _columns[column.ColumnIndex] = column;
        }

        public ListViewColumn GetColumn(int index)
        {
            ListViewColumn column;
            return _columns.TryGetValue(index, out column) ? column : null;
        }

        public IEnumerable<ListViewColumn> Columns
        {
            get
            {
                return _columns.Values;
            }
        }

        public virtual void Dispose()
        {
            if (Font != null)
            {
                Font.Dispose();
                Font = null;
            }
        }
    }

    public abstract class ListViewColumn
    {
        public event EventHandler<ListViewColumnMouseEventArgs> Click;

        protected ListViewColumn(int columnIndex)
        {
            if (columnIndex < 0)
                throw new ArgumentException(null, "columnIndex");

            ColumnIndex = columnIndex;
        }

        public virtual ListViewExtender Extender { get; protected internal set; }
        public int ColumnIndex { get; private set; }

        public virtual Font Font
        {
            get
            {
                return Extender == null ? null : Extender.Font;
            }
        }

        public ListView ListView
        {
            get
            {
                return Extender == null ? null : Extender.ListView;
            }
        }

        public abstract void Draw(DrawListViewSubItemEventArgs e);

        public virtual void MouseClick(MouseEventArgs e, ListViewItem item, ListViewItem.ListViewSubItem subItem)
        {
            if (Click != null)
            {
                Click(this, new ListViewColumnMouseEventArgs(e, item, subItem));
            }
        }

        public virtual void Invalidate(ListViewItem item, ListViewItem.ListViewSubItem subItem)
        {
            if (Extender != null)
            {
                Extender.ListView.Invalidate(subItem.Bounds);
            }
        }
    }

    public class ListViewColumnMouseEventArgs : MouseEventArgs
    {
        public ListViewColumnMouseEventArgs(MouseEventArgs e, ListViewItem item, ListViewItem.ListViewSubItem subItem)
            : base(e.Button, e.Clicks, e.X, e.Y, e.Delta)
        {
            Item = item;
            SubItem = subItem;
        }

        public ListViewItem Item { get; private set; }
        public ListViewItem.ListViewSubItem SubItem { get; private set; }
    }

    public class ListViewButtonColumn : ListViewColumn
    {
        private Rectangle _hot = Rectangle.Empty;

        public ListViewButtonColumn(int columnIndex)
            : base(columnIndex)
        {
        }

        public bool FixedWidth { get; set; }
        public bool DrawIfEmpty { get; set; }

        public override ListViewExtender Extender
        {
            get
            {
                return base.Extender;
            }
            protected internal set
            {
                base.Extender = value;
                if (FixedWidth)
                {
                    base.Extender.ListView.ColumnWidthChanging += OnColumnWidthChanging;
                }
            }
        }

        protected virtual void OnColumnWidthChanging(object sender, ColumnWidthChangingEventArgs e)
        {
            if (e.ColumnIndex == ColumnIndex)
            {
                e.Cancel = true;
                e.NewWidth = ListView.Columns[e.ColumnIndex].Width;
            }
        }

        public override void Draw(DrawListViewSubItemEventArgs e)
        {
            if (_hot != Rectangle.Empty)
            {
                if (_hot != e.Bounds)
                {
                    ListView.Invalidate(_hot);
                    _hot = Rectangle.Empty;
                }
            }

            if ((!DrawIfEmpty) && (string.IsNullOrEmpty(e.SubItem.Text)))
                return;

            Point mouse = e.Item.ListView.PointToClient(Control.MousePosition);
            if ((ListView.GetItemAt(mouse.X, mouse.Y) == e.Item) && (e.Item.GetSubItemAt(mouse.X, mouse.Y) == e.SubItem))
            {
                ButtonRenderer.DrawButton(e.Graphics, e.Bounds, e.SubItem.Text, Font, true, PushButtonState.Hot);
                _hot = e.Bounds;
            }
            else
            {
                ButtonRenderer.DrawButton(e.Graphics, e.Bounds, e.SubItem.Text, Font, false, PushButtonState.Default);
            }
        }
    }
}
作者: Simon Mourier 发布者: 2010 年 12 月 28 日

7

4463 作者的声誉

这是WinForms 的最佳自定义列表视图控件。
ObjectListView

作者: AZ. 发布者: 2011 年 2 月 25 日

-2

5 作者的声誉

这看起来像最简单的答案,我所遇到的...只是增加了一个ItemCommandListView

请参阅此链接:handle-the-button-click-event-from-an-asp-net-listview-control

作者: Zwinggi 发布者: 2012 年 7 月 4 日

3

588 作者的声誉

为了使Simon Mourier的扩展工作缺少以下几行:

extender.AddColumn(buttonAction);

这是,它应该看起来像:

ListViewExtender extender = new ListViewExtender(listSummary);
ListViewButtonColumn buttonAction = new ListViewButtonColumn(2);
buttonAction.Click += OnButtonActionClick;
buttonAction.FixedWidth = true;
extender.AddColumn(buttonAction);
作者: pinker 发布者: 2012 年 8 月 19 日

0

1 作者的声誉

你可以使用GlacialList。它允许您将任何控件放在列表单元格中,并且使用起来很简单。您只需将GlacialList.dll文档加入解决方案的参考部分即可。如果单击该链接,它将显示它的工作原理以及如何使用和下载。

如果您有上述链接中System.IO.FileNotFoundExceptionInitializeComponent()刚下载源代码,请编译并使用此.dll(在bin / Debug子文件夹内)到您的项目。

以下是它的外观示例:

例

作者: Mystic 发布者: 2019 年 8 月 14 日
32x32