这可能会让你开始。
首先,将OwnerDraw 设置为true,将HideSelection 设置为False。然后,我们需要摆弄一些事件。 OwnerDraw 可能是一件苦差事,因为这意味着您必须处理所有项目、子项目和列标题的绘制。幸运的是,对于您想要的来说,这还不错:
// do the default
private void ListView1_DrawColumnHeader(object sender,
DrawListViewColumnHeaderEventArgs e)
{
e.DrawDefault = true;
}
由于Item.Text也是SubItem(0),你可以跳过DrawItem直接回复DrawSubItem:
private void listView1_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
{
if (!object.ReferenceEquals(this.ActiveControl, listView1) && (e.ItemIndex != -1))
{
// ToDo offer an early exit if HideSelection is false (?)
if (e.Item.Selected)
{
e.Graphics.FillRectangle(new SolidBrush(SystemColors.Highlight),
e.Bounds);
TextRenderer.DrawText(
e.Graphics, " " + listView1.Items(e.ItemIndex).SubItems(e.ColumnIndex).Text,
listView1.Font, e.Bounds,
SystemColors.HighlightText, SystemColors.Highlight,
TextFormatFlags.Left | TextFormatFlags.VerticalCenter
);
// default method seems off a little
//e.DrawText(TextFormatFlags.Left Or TextFormatFlags.VerticalCenter)
} else {
e.DrawDefault = true;
}
} else {
e.DrawDefault = true;
}
}
注意事项:
直到我编码后我才注意到它被标记为 C#,所以从 VB 的翻译可能会在这里和那里有点偏离。它会填充一个比默认绘制操作稍大的矩形。明天我不饿的时候再检查一下。
按原样,它使用默认的SystemColors。因为它没有有焦点,我认为它可能会稍微减轻背景颜色,所以它确实看起来与没有焦点不同。看看你是否喜欢这个结果:
Private Function LightenColor(clr As Color, amt As Double) As Color
Dim R, G, B As Integer
R = Convert.ToInt32(Math.Min(255, clr.R + 255 * amt))
G = Convert.ToInt32(Math.Min(255, clr.G + 255 * amt))
B = Convert.ToInt32(Math.Min(255, clr.B + 255 * amt))
Return Color.FromArgb(clr.A, R, G, B)
End Function
转换成 C# 后,用它定义一个新的较浅的选定颜色:
// small values make a BIG difference
Color InActiveHighlight = LightenColor(SystemColors.Highlight, 0.15);
然后使用InActiveHighlight 作为FillRectangle 和TextRenderer 的背景颜色参数。结果:
这不是太明显,但是正常的油漆在左边留下了 2-3px 的小间距。
我不太确定闪电是个好主意。首先,任何较浅的和默认的文本颜色都不会有足够的对比度;其次,它可以使它在一个黑暗的主题上更加——而不是更少——引人注目;最后,如果SystemColors.Highlight 在不活动时对于ListBox 来说足够好,那么对于ListView 也应该足够好。