我想在列表視圖中更改項目的/行的高度。C#更改列表視圖項/行的高度
我搜索了每一處,我發現爲了改變高度,我需要使用LBS_OWNERDRAWFIXED
或MeasureItem
或類似的東西。
問題是,我不知道該怎麼辦以及如何使用它..
任何人都可以幫我嗎?
編輯:
我,因爲我使用的是SmallImageList真正不能使用的ImageList背,我需要不同的線高度從ImageList中的圖像大小。
謝謝!
我想在列表視圖中更改項目的/行的高度。C#更改列表視圖項/行的高度
我搜索了每一處,我發現爲了改變高度,我需要使用LBS_OWNERDRAWFIXED
或MeasureItem
或類似的東西。
問題是,我不知道該怎麼辦以及如何使用它..
任何人都可以幫我嗎?
編輯:
我,因爲我使用的是SmallImageList真正不能使用的ImageList背,我需要不同的線高度從ImageList中的圖像大小。
謝謝!
它可以通過SmallImageList
技巧來完成 - 你就必須要小心。 ObjectListView - 圍繞標準.NET開放源代碼包裝器ListView
- 使用該技巧成功實現RowHeight
屬性。
如果您需要每行32像素,請分配一個爲16x32(寬x高)的ImageList
,然後將每個圖像放置在32像素高度的垂直中間位置。
此屏幕截圖顯示32像素行和自動換行這是因爲額外的空間可能:
ObjectListView
做這一切爲你工作。事實上,如果你想用ListView做任何事情,你應該認真考慮使用ObjectListView
來代替。它使許多困難的事情(例如,按列類型排序,自定義工具提示)變得微不足道,並且幾個不可能的事情(例如覆蓋,虛擬列表上的組)也是可能的。
那麼,我只是想調整行大小和300kb,因爲我計劃的程序太多了。無論如何,這是一個很好的解決方案。 – Ron
我認爲你提出了一個如此複雜的解決方案 –
你必須使用一點黑客。訣竅是在StateImageList屬性中使用圖像列表。 ListView將根據ImageList的ImageSize屬性的高度來調整它的項目高度。您不必爲項目指定圖像,但僅使用StateImageList將強制ListView進行調整。在下面的示例中,我將圖像列表大小設置爲32x32,因此生成32px高度的ListViewItem(s)。
我忘了說,我在SmallImageList proeprty中使用ImageList,所以我不能使用該黑客。 – Ron
然後,你將不得不編寫自己的控件,因爲從經驗和研究來看,對於現有的WinForms ListView來說這是不可能的。這也是來自MSFT社區支持開發人員的同樣迴應,他們也爲一些人研究了這個問題,並最終建議編寫一個自定義控件。 –
我在詳細模式下測試了這個。這個技巧僅用於增加超出高度的行高度。你不能使行比Windows定義的更緊密。請注意列表視圖行的高度取決於操作系統。例如,在Windows 7上,行數比在XP上高得多。可悲的是,這個技巧對我來說並不有用。 – Elmue
根據控件的字體大小計算ListView的默認行高(在報表視圖模式下)。
因此,要選擇行高,請在ListView屬性中選擇具有正確高度的字體。 例如,選擇MS無襯線18
然後你就可以更改所有項目所使用的字體: 當你插入一個新的項目,設置其字體屬性。
要優化字體的設置,你應該申報的項目字體作爲形式的私有成員:
Private Font stdfont = new Font("Consolas", 9.0f, FontStyle.Regular);
然後加入項目時:
ListViewItem i = new ListViewItem("some text");
i.Font = stdfont;
MyListView.Items.Add(i);
這招是唯一容易的允許有較小的線高;) iE設置控件的字體大小爲7,並設置項目字體大小10 (測試用VS 2008)
對於仍與此strugling的人來說,這裏是我的代碼使用方法:
private void SetHeight(ListView listView, int height)
{
ImageList imgList = new ImageList();
imgList.ImageSize = new Size(1, height);
listView.SmallImageList = imgList;
}
要使用這只是做:
SetHeight(lvConnections, 25);
我在詳細模式下對此進行了測試。這個技巧僅用於增加超出高度的行高度。你不能使行比Windows定義的更緊密。請注意列表視圖行的高度取決於操作系統。例如,在Windows 7上,行數比在XP上高得多。可悲的是,這個技巧對我來說並不有用。 – Elmue
Plasmabubble有正確的想法。這擴大了這一點,我正在使用一個狹窄的線條寬度的項目。
在ListView的linespacing取決於ListView的字體,不能更改。但是,您可以將ListView中項目的字體設置爲比ListView字體更大的字體。
如果你希望它是成比例的,創建一個基於項目的字體的字體。 我想要的項目高度爲90%的正常的,無論字體選擇。
當我填充列表我用存儲在設置的字體,但你也可以使用文字的字體,如「索拉」。
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;
<dot><dot><dot>
}
可悲的是沒有人回答你原來的問題是如何在這些年來使用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;
/// <summary>
/// Constructor
/// </summary>
public ListViewEx()
{
SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
}
/// <summary>
/// Sets the row height in Details view
/// This property appears in the Visual Studio Form Designer
/// </summary>
[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;
}
}
/// <summary>
/// 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()
/// </summary>
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; S<i_Item.SubItems.Count; S++)
{
ListViewItem.ListViewSubItem i_SubItem = i_Item.SubItems[S];
// i_Item.SubItems[0].Bounds contains the entire row, rather than the first column only.
Rectangle k_Bounds = (S>0) ? 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窗體設計器,允許設置在像素的行高度的新特性:
您輸入的值將是以像素爲單位的行高度,並且在所有操作系統上都將嚴格遵守。我測試了它在Windows XP,Windows 7和10:
另外我班有超過原來的ListView兩個優點:它吸引了無閃爍並尊重前景色和字體設置爲ListViewSubItem
,它被原始的Microsoft ListView忽略。所以你可以用不同的顏色和字體繪製每個單元格。
重要:由於MSDN說LBS_OWNERDRAWFIXED
已設計只的詳細信息視圖(報表視圖)。我的代碼僅適用於此模式,這是因爲Microsoft已經這樣設計它。
此外請注意,設置ListView.OwnerDraw = true
是完全不同的東西比使用LVS_OWNERDRAWFIXED
。
我沒有執行繪圖圖標,因爲我不需要那個。但是你可以很容易地添加這個。
CreateParams覆蓋導致子項目文本不顯示... – user1932634
我完全不知道你在說什麼。我在我的應用程序中使用此代碼。它完美的工作!在上面的屏幕截圖中,您可以看到所有子項都可以正確繪製,即使是彩色的。 – Elmue
請參閱http://stackoverflow.com/questions/1244090/how-to-set-wpf-listview-row-height。解決方案簡單 – 2014-06-03 16:53:41
提到的「簡單解決方案」是針對WPF的 - 確實很簡單。這個問題是關於WinForms - 它決定不簡單。 – Grammarian