C#更改ListView项目/行的高度

我想在listview中更改Item的/ Row的高度。

我搜索了每一个地方,我想,为了改变高度,我需要使用LBS_OWNERDRAWFIXEDMeasureItem或类似的东西。

问题是我不知道该做什么以及如何使用它。
任何人都可以帮助我吗?

编辑:
我不能使用ImageList黑客,因为我使用SmallImageList是真实的,我需要从ImageList图像大小不同的行高。

谢谢!

它可以使用SmallImageList技巧完成 – 你必须要小心。 ObjectListView – 围绕标准.NET ListView开源包装器 – 使用该技巧成功实现RowHeight属性。

如果每行需要32个像素,请分配一个16×32(宽x高)的ImageList ,然后将每个图像放在32像素高度的垂直中间位置。

此屏幕截图显示32像素行和由于额外空间可能的自动换行:

在此处输入图像描述

ObjectListView为您完成所有这些工作。 实际上,如果您尝试使用ListView执行任何操作,则应该认真考虑使用ObjectListView 。 它使许多困难的事情(例如按列类型排序,自定义工具提示)变得微不足道,并且几个不可能的事情(例如覆盖,虚拟列表上的组)成为可能。

对于仍在努力解决这个问题的人来说,这里是我使用的代码:

 private void SetHeight(ListView listView, int height) { ImageList imgList = new ImageList(); imgList.ImageSize = new Size(1, height); listView.SmallImageList = imgList; } 

要使用它,只需:

 SetHeight(lvConnections, 25); 

你必须使用一些黑客。 诀窍是在StateImageList属性中使用图像列表。 ListView将根据ImageList的ImageSize属性的高度调整其项高度。 您不必为项目指定图像,但只使用StateImageList将强制ListView进行调整。 在下面的示例中,我将图像列表大小设置为32×32,从而产生32px高度的ListViewItem(s)。

在此处输入图像描述

ListView的默认行高(在报表视图模式下)是根据控件的字体大小计算的。

因此,要选择行高,请在ListView属性中选择具有正确高度的字体。 例如,选择MS Sans Serif 18。

然后,您可以更改所有项目使用的字体:插入新项目时,设置其字体属性。

要优化字体分配,您应该将项目字体声明为表单的私有成员:

 Private Font stdfont = new Font( "Consolas", 9.0f, FontStyle.Regular ); 

然后在添加项目时:

 ListViewItem i = new ListViewItem( "some text" ); i.Font = stdfont; MyListView.Items.Add( i ); 

这个技巧是唯一一个允许SMALLER行高的简单方法;)iE将控件的字体大小设置为7并将项目的字体大小设置为10.(使用VS 2008测试)

可悲的是,在这些年里,没有人回答你原来的问题如何使用LBS_OWNERDRAWFIXED

您接受的答案是整合一个庞大的项目(演示和文档3,3MB)。 但仅仅为了设置ListView的行高,这是过度浮动的。

此处建议的其他解决方法(添加ImageList)仅用于增加行高。 但它不允许真正设置RowHeight独立于图像高度。 此外,默认行高取决于操作系统。 例如,在Windows 7上,行数远高于XP。 你不能选择让它们更紧,只有更高。

但只有很少的线条,你可以做你想要的。 只需复制并粘贴以下类:

 using System; using System.Drawing; using System.Diagnostics; using System.ComponentModel; using System.Runtime.InteropServices; using System.Windows.Forms; namespace ExtendedControls { public class ListViewEx : ListView { #region Windows API /* struct MEASUREITEMSTRUCT { public int CtlType; // Offset = 0 public int CtlID; // Offset = 1 public int itemID; // Offset = 2 public int itemWidth; // Offset = 3 public int itemHeight; // Offset = 4 public IntPtr itemData; } */ [StructLayout(LayoutKind.Sequential)] struct DRAWITEMSTRUCT { public int ctlType; public int ctlID; public int itemID; public int itemAction; public int itemState; public IntPtr hWndItem; public IntPtr hDC; public int rcLeft; public int rcTop; public int rcRight; public int rcBottom; public IntPtr itemData; } // LVS_OWNERDRAWFIXED: The owner window can paint ListView items in report view. // The ListView control sends a WM_DRAWITEM message to paint each item. It does not send separate messages for each subitem. const int LVS_OWNERDRAWFIXED = 0x0400; const int WM_SHOWWINDOW = 0x0018; const int WM_DRAWITEM = 0x002B; const int WM_MEASUREITEM = 0x002C; const int WM_REFLECT = 0x2000; #endregion bool mb_Measured = false; int ms32_RowHeight = 14; ///  /// Constructor ///  public ListViewEx() { SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true); } ///  /// Sets the row height in Details view /// This property appears in the Visual Studio Form Designer ///  [Category("Appearance")] [Description("Sets the height of the ListView rows in Details view in pixels.")] public int RowHeight { get { return ms32_RowHeight; } set { if (!DesignMode) Debug.Assert(mb_Measured == false, "RowHeight must be set before ListViewEx is created."); ms32_RowHeight = value; } } protected override CreateParams CreateParams { get { CreateParams k_Params = base.CreateParams; k_Params.Style |= LVS_OWNERDRAWFIXED; return k_Params; } } ///  /// The messages WM_MEASUREITEM and WM_DRAWITEM are sent to the parent control rather than to the ListView itself. /// They come here as WM_REFLECT + WM_MEASUREITEM and WM_REFLECT + WM_DRAWITEM /// They are sent from Control.WmOwnerDraw() --> Control.ReflectMessageInternal() ///  protected override void WndProc(ref Message k_Msg) { base.WndProc(ref k_Msg); // FIRST switch (k_Msg.Msg) { case WM_SHOWWINDOW: // called when the ListView becomes visible { Debug.Assert(View == View.Details, "ListViewEx supports only Details view"); Debug.Assert(OwnerDraw == false, "In ListViewEx do not set OwnerDraw = true"); break; } case WM_REFLECT + WM_MEASUREITEM: // called once when the ListView is created, but only in Details view { mb_Measured = true; // Overwrite itemHeight, which is the fifth integer in MEASUREITEMSTRUCT Marshal.WriteInt32(k_Msg.LParam + 4 * sizeof(int), ms32_RowHeight); k_Msg.Result = (IntPtr)1; break; } case WM_REFLECT + WM_DRAWITEM: // called for each ListViewItem to be drawn { DRAWITEMSTRUCT k_Draw = (DRAWITEMSTRUCT) k_Msg.GetLParam(typeof(DRAWITEMSTRUCT)); using (Graphics i_Graph = Graphics.FromHdc(k_Draw.hDC)) { ListViewItem i_Item = Items[k_Draw.itemID]; Color c_BackColor = i_Item.BackColor; if (i_Item.Selected) c_BackColor = SystemColors.Highlight; if (!Enabled) c_BackColor = SystemColors.Control; using (SolidBrush i_BackBrush = new SolidBrush(c_BackColor)) { // Erase the background of the entire row i_Graph.FillRectangle(i_BackBrush, i_Item.Bounds); } for (int S=0; S0) ? i_SubItem.Bounds : i_Item.GetBounds(ItemBoundsPortion.Label); // You can use i_Item.ForeColor instead of i_SubItem.ForeColor to get the same behaviour as without OwnerDraw Color c_ForeColor = i_SubItem.ForeColor; if (i_Item.Selected) c_ForeColor = SystemColors.HighlightText; if (!Enabled) c_ForeColor = SystemColors.ControlText; TextFormatFlags e_Flags = TextFormatFlags.NoPrefix | TextFormatFlags.EndEllipsis | TextFormatFlags.VerticalCenter | TextFormatFlags.SingleLine; switch (Columns[S].TextAlign) { case HorizontalAlignment.Center: e_Flags |= TextFormatFlags.HorizontalCenter; break; case HorizontalAlignment.Right: e_Flags |= TextFormatFlags.Right; break; } TextRenderer.DrawText(i_Graph, i_SubItem.Text, i_SubItem.Font, k_Bounds, c_ForeColor, e_Flags); } } break; } } } } // class } // namespace 

将ListViewEx添加到表单后,您将在Visual Studio窗体设计器中看到一个新属性,该属性允许以像素为单位设置行高:

在C#ListView中设置RowHeight

您输入的值将是行高(以像素为单位),并且在所有操作系统上都会得到很好的尊重。 我在Windows XP,7和10上测试过它:

ListViewEx.RowHeight示例

此外,我的类比原始ListView还有两个优点:它无闪烁 ,它尊重ListViewSubItem中设置的ForeColorFont ,原始的Microsoft ListView会忽略它。 因此,您可以使用不同的颜色和字体绘制每个单元格。

重要提示:正如MSDN所说, LBS_OWNERDRAWFIXED 针对详细信息视图(报表视图)设计。 我的代码仅适用于此模式,这是因为Microsoft已经设计了这样的模式。

另请注意,设置ListView.OwnerDraw = true与使用LVS_OWNERDRAWFIXED完全不同。

我没有实现绘图图标 ,因为我不需要它。 但你可以轻松添加这个。

Plasmabubble有正确的想法。 这扩展了这一点,我使用的是使用窄线宽的项目。

ListView中的行间距取决于ListView的字体,无法更改。 但是,您可以将ListView中的项目的字体设置为大于ListView的字体。

如果您希望它成比例,请根据项目的字体创建字体。 无论选择哪种字体,我希望项目高度为正常值的90%。

当我填充列表时,我使用了存储在设置中的字体,但您也可以使用像“Consolas”这样的文字字体。

 lvResults.Font = new Font(Properties.Settings.Default.usrHookFont.FontFamily, (float)(Properties.Settings.Default.usrHookFont.Size * .9)); foreach (HookSet item in resultSet) { ListViewItem lvi = new ListViewItem(); lvi.Font = Properties.Settings.Default.usrHookFont;  }