如何更改 ListView 的默认选择颜色?
How to change default selection color of a ListView?
我正在尝试更改 ListView 中选择栏的默认(蓝色)颜色。
我拒绝使用 ObjectListView,因为我必须更改所有代码。
我搜索过这个主题并在这里找到了一些答案:
Change background selection color of ListView?
但这指向 ObjectListView。
当我以前使用 ListBox 时,这可以根据我的喜好设置选择栏颜色:
- 在属性
下将 DrawMode 设置为 OwnerDrawFixed
- 在事件
下将 DrawItem 设置为 ListBox1_DrawItem
private void ListBox1_DrawItem(object sender, DrawItemEventArgs e)
{
if (e.Index < 0) return;
//if the item state is selected them change the back color
if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
e = new DrawItemEventArgs(e.Graphics,
e.Font,
e.Bounds,
e.Index,
e.State ^ DrawItemState.Selected,
e.ForeColor,
Color.FromArgb(43, 144, 188));//Choose the color
// Draw the background of the ListBox control for each item.
e.DrawBackground();
// Draw the current item text
e.Graphics.DrawString(lb_result.Items[e.Index].ToString(), e.Font, Brushes.Black, e.Bounds, StringFormat.GenericDefault);
// If the ListBox has focus, draw a focus rectangle around the selected item.
e.DrawFocusRectangle();
}
但我现在正在使用 ListView。
- 我将
OwnerDraw
设置为 True
- 我将 DrawItem 设置为
ListView1_DrawItem
...并使用上面的代码。
我原以为它会按照说明显示不同的选择颜色,但我却遇到了一些错误:
如何为 ListView 正确使用此代码?
Owner-drawing ListView 控件比 ListBox 控件更复杂:需要处理更多细节。
这是一个考虑 ListView 的四个 View 设置的示例:
View.Details
、View.List
、View.Tile
和 View.SmallIcon
.
这里只绘制了文本(这就是 View.LargeIcon
未包括在内的原因),以将代码包含在合适的范围内。
绘制链接到 ListView 的 ImageList 中包含的位图的示例是 here.
设置ListView:
启用您的 ListView OwnerDraw
模式,然后订阅其 DrawItem, DrawSubItem and DrawColumnHeader 事件,如示例代码所示(强制性,如果您希望 ListView 显示任何内容)。
Headers使用默认渲染绘制(设置e.DrawDefault = true
)。
常用操作说明:
使用 TextRenderer.DrawText 绘制项目文本:这是 ListView 用于绘制其项目的原始方法。它允许完全匹配默认呈现,因此我们不会注意到某些 mis-alignment 文本。
DrawItem
事件用于在所有 View
模式下绘制自定义背景,并将在除 View.Details,其中 DrawSubItems
事件开始发挥作用:如果 DrawItem
事件执行相同的任务,我们将绘制第一个项目的文本两次。
当 View
设置为 Tile
或 List
.[=34 时,不会调用 DrawSubItems
事件 =]
此处提供的代码的详细信息:
辅助方法 GetTextAlignment
负责设置项目的对齐方式,因为每个列都可以有特定的文本对齐方式。
字段 Color listViewSelectionColor
用于 set/change select 项的颜色。要修改 selection 颜色,请将此字段设置为任意值,然后 Invalidate()
ListView:将立即应用新颜色。
结果样本:
bool lvEditMode = false;
Color listViewSelectionColor = Color.Orange;
protected void listView1_DrawItem(object sender, DrawListViewItemEventArgs e)
{
var lView = sender as ListView;
if (lvEditMode || lView.View == View.Details) return;
TextFormatFlags flags = GetTextAlignment(lView, 0);
Color itemColor = e.Item.ForeColor;
if (e.Item.Selected) {
using (var bkBrush = new SolidBrush(listViewSelectionColor)) {
e.Graphics.FillRectangle(bkBrush, e.Bounds);
}
itemColor = e.Item.BackColor;
}
else {
e.DrawBackground();
}
TextRenderer.DrawText(e.Graphics, e.Item.Text, e.Item.Font, e.Bounds, itemColor, flags);
if (lView.View == View.Tile && e.Item.SubItems.Count > 1) {
var subItem = e.Item.SubItems[1];
flags = GetTextAlignment(lView, 1);
TextRenderer.DrawText(e.Graphics, subItem.Text, subItem.Font, e.Bounds, SystemColors.GrayText, flags);
}
}
private void listView1_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
{
var lView = sender as ListView;
TextFormatFlags flags = GetTextAlignment(lView, e.ColumnIndex);
Color itemColor = e.Item.ForeColor;
if (e.Item.Selected && !lvEditMode) {
if (e.ColumnIndex == 0 || lView.FullRowSelect) {
using (var bkgrBrush = new SolidBrush(listViewSelectionColor)) {
e.Graphics.FillRectangle(bkgrBrush, e.Bounds);
}
itemColor = e.Item.BackColor;
}
}
else {
e.DrawBackground();
}
TextRenderer.DrawText(e.Graphics, e.SubItem.Text, e.SubItem.Font, e.Bounds, itemColor, flags);
}
protected void listView1_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
=> e.DrawDefault = true;
private TextFormatFlags GetTextAlignment(ListView lstView, int colIndex)
{
TextFormatFlags flags = (lstView.View == View.Tile)
? (colIndex == 0) ? TextFormatFlags.Default : TextFormatFlags.Bottom
: TextFormatFlags.VerticalCenter;
if (lstView.View == View.Details) flags |= TextFormatFlags.LeftAndRightPadding;
if (lstView.Columns[colIndex].TextAlign != HorizontalAlignment.Left) {
flags |= (TextFormatFlags)((int)lstView.Columns[colIndex].TextAlign ^ 3);
}
return flags;
}
private void listView1_BeforeLabelEdit(object sender, LabelEditEventArgs e) => lvEditMode = true;
private void listView1_AfterLabelEdit(object sender, LabelEditEventArgs e) => lvEditMode = false;
我正在尝试更改 ListView 中选择栏的默认(蓝色)颜色。
我拒绝使用 ObjectListView,因为我必须更改所有代码。
我搜索过这个主题并在这里找到了一些答案:
Change background selection color of ListView?
但这指向 ObjectListView。
当我以前使用 ListBox 时,这可以根据我的喜好设置选择栏颜色:
- 在属性 下将 DrawMode 设置为
- 在事件 下将 DrawItem 设置为
OwnerDrawFixed
ListBox1_DrawItem
private void ListBox1_DrawItem(object sender, DrawItemEventArgs e)
{
if (e.Index < 0) return;
//if the item state is selected them change the back color
if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
e = new DrawItemEventArgs(e.Graphics,
e.Font,
e.Bounds,
e.Index,
e.State ^ DrawItemState.Selected,
e.ForeColor,
Color.FromArgb(43, 144, 188));//Choose the color
// Draw the background of the ListBox control for each item.
e.DrawBackground();
// Draw the current item text
e.Graphics.DrawString(lb_result.Items[e.Index].ToString(), e.Font, Brushes.Black, e.Bounds, StringFormat.GenericDefault);
// If the ListBox has focus, draw a focus rectangle around the selected item.
e.DrawFocusRectangle();
}
但我现在正在使用 ListView。
- 我将
OwnerDraw
设置为 True - 我将 DrawItem 设置为
ListView1_DrawItem
...并使用上面的代码。
我原以为它会按照说明显示不同的选择颜色,但我却遇到了一些错误:
如何为 ListView 正确使用此代码?
Owner-drawing ListView 控件比 ListBox 控件更复杂:需要处理更多细节。
这是一个考虑 ListView 的四个 View 设置的示例:
View.Details
、View.List
、View.Tile
和 View.SmallIcon
.
这里只绘制了文本(这就是 View.LargeIcon
未包括在内的原因),以将代码包含在合适的范围内。
绘制链接到 ListView 的 ImageList 中包含的位图的示例是 here.
设置ListView:
启用您的 ListView OwnerDraw
模式,然后订阅其 DrawItem, DrawSubItem and DrawColumnHeader 事件,如示例代码所示(强制性,如果您希望 ListView 显示任何内容)。
Headers使用默认渲染绘制(设置e.DrawDefault = true
)。
常用操作说明:
使用 TextRenderer.DrawText 绘制项目文本:这是 ListView 用于绘制其项目的原始方法。它允许完全匹配默认呈现,因此我们不会注意到某些 mis-alignment 文本。
DrawItem
事件用于在所有 View
模式下绘制自定义背景,并将在除 View.Details,其中 DrawSubItems
事件开始发挥作用:如果 DrawItem
事件执行相同的任务,我们将绘制第一个项目的文本两次。
当 此处提供的代码的详细信息: 字段 结果样本:View
设置为 Tile
或 List
.[=34 时,不会调用 DrawSubItems
事件 =]
辅助方法 GetTextAlignment
负责设置项目的对齐方式,因为每个列都可以有特定的文本对齐方式。Color listViewSelectionColor
用于 set/change select 项的颜色。要修改 selection 颜色,请将此字段设置为任意值,然后 Invalidate()
ListView:将立即应用新颜色。bool lvEditMode = false;
Color listViewSelectionColor = Color.Orange;
protected void listView1_DrawItem(object sender, DrawListViewItemEventArgs e)
{
var lView = sender as ListView;
if (lvEditMode || lView.View == View.Details) return;
TextFormatFlags flags = GetTextAlignment(lView, 0);
Color itemColor = e.Item.ForeColor;
if (e.Item.Selected) {
using (var bkBrush = new SolidBrush(listViewSelectionColor)) {
e.Graphics.FillRectangle(bkBrush, e.Bounds);
}
itemColor = e.Item.BackColor;
}
else {
e.DrawBackground();
}
TextRenderer.DrawText(e.Graphics, e.Item.Text, e.Item.Font, e.Bounds, itemColor, flags);
if (lView.View == View.Tile && e.Item.SubItems.Count > 1) {
var subItem = e.Item.SubItems[1];
flags = GetTextAlignment(lView, 1);
TextRenderer.DrawText(e.Graphics, subItem.Text, subItem.Font, e.Bounds, SystemColors.GrayText, flags);
}
}
private void listView1_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
{
var lView = sender as ListView;
TextFormatFlags flags = GetTextAlignment(lView, e.ColumnIndex);
Color itemColor = e.Item.ForeColor;
if (e.Item.Selected && !lvEditMode) {
if (e.ColumnIndex == 0 || lView.FullRowSelect) {
using (var bkgrBrush = new SolidBrush(listViewSelectionColor)) {
e.Graphics.FillRectangle(bkgrBrush, e.Bounds);
}
itemColor = e.Item.BackColor;
}
}
else {
e.DrawBackground();
}
TextRenderer.DrawText(e.Graphics, e.SubItem.Text, e.SubItem.Font, e.Bounds, itemColor, flags);
}
protected void listView1_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
=> e.DrawDefault = true;
private TextFormatFlags GetTextAlignment(ListView lstView, int colIndex)
{
TextFormatFlags flags = (lstView.View == View.Tile)
? (colIndex == 0) ? TextFormatFlags.Default : TextFormatFlags.Bottom
: TextFormatFlags.VerticalCenter;
if (lstView.View == View.Details) flags |= TextFormatFlags.LeftAndRightPadding;
if (lstView.Columns[colIndex].TextAlign != HorizontalAlignment.Left) {
flags |= (TextFormatFlags)((int)lstView.Columns[colIndex].TextAlign ^ 3);
}
return flags;
}
private void listView1_BeforeLabelEdit(object sender, LabelEditEventArgs e) => lvEditMode = true;
private void listView1_AfterLabelEdit(object sender, LabelEditEventArgs e) => lvEditMode = false;