-
Notifications
You must be signed in to change notification settings - Fork 0
/
StripListView.cs
148 lines (128 loc) · 5.85 KB
/
StripListView.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
//+--------------------------------------------------------------------------
//
// NightDriverDesktop - (c) 2024 Dave Plummer. All Rights Reserved.
//
// File: StripListView.cs
//
// Description:
//
// Specialization of the listview for use in showing the main strip list.
//
// History: Dec-23-2023 Davepl Created
//
//---------------------------------------------------------------------------
using Newtonsoft.Json.Linq;
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using System.Xml;
using static System.Windows.Forms.AxHost;
namespace NightDriver
{
internal class StripListView : ListView
{
private ListViewGroup _selectedGroup; // Field to store the selected group
public StripListView()
{
// Activate double buffering
SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
// Enable notify messages so we get a shot at WM_ERASEBKGND
SetStyle(ControlStyles.EnableNotifyMessage, true);
// Attach event handlers for custom drawing
this.OwnerDraw = true;
this.DrawItem += StripListView_DrawItem;
this.DrawSubItem += StripListView_DrawSubItem;
this.DrawColumnHeader += StripListView_DrawColumnHeader;
this.MouseClick += StripListView_MouseClick;
}
private void StripListView_DrawItem(object sender, DrawListViewItemEventArgs e)
{
StripListView stripListView = (StripListView)sender;
// Draw the background of the item, handling selection state
if (e.Item.Selected)
{
// Draw selected background
e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(192,192,192)), e.Bounds);
}
else
{
// Draw default background
e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(220, 220, 220)), e.Bounds);
}
// Let the default handler draw the rest of the items
e.DrawDefault = false;
}
private void StripListView_MouseClick(object sender, MouseEventArgs e)
{
// Get the item at the mouse click location
var hitTestInfo = HitTest(e.Location);
if (hitTestInfo.Item != null && hitTestInfo.SubItem != null)
{
// Get the bounds of the first subitem (checkbox column)
Rectangle subItemBounds = hitTestInfo.SubItem.Bounds;
// Get the size of the system checkbox
Size checkBoxSize = SystemInformation.MenuCheckSize;
// Define the checkbox bounds relative to the subitem bounds
Rectangle checkBounds = new Rectangle(subItemBounds.Left + 4, subItemBounds.Top + 4, checkBoxSize.Width + 8, checkBoxSize.Height + 8);
// Check if the click is within the checkbox bounds (translated into control coordinates)
if (hitTestInfo.Item.Tag == null && hitTestInfo.Item.SubItems.IndexOf(hitTestInfo.SubItem) == 0 && checkBounds.Contains(e.Location))
{
// Toggle the checked state
hitTestInfo.Item.Checked = !hitTestInfo.Item.Checked;
// Redraw the item to reflect the checkbox state change
Invalidate(hitTestInfo.SubItem.Bounds);
// Raise item changed event
OnItemChecked(new ItemCheckedEventArgs(hitTestInfo.Item));
}
}
}
// Handle drawing of sub-items (default handling)
private void StripListView_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
{
Size checkBoxSize = SystemInformation.MenuCheckSize;
if (e.Item.Tag == null)
{
// Custom drawing for items with null Tag
e.Graphics.FillRectangle(e.Item.Selected ? Brushes.Black : new SolidBrush(Color.FromArgb(150, 190, 255)), e.Bounds);
// Draw the checkbox
if (e.ColumnIndex == 0)
{
Rectangle bounds = e.Bounds;
CheckBoxRenderer.DrawCheckBox(e.Graphics,
new Point(bounds.Left + 4, bounds.Top + 4),
e.Item.Checked ? CheckBoxState.CheckedNormal : CheckBoxState.UncheckedNormal);
}
// Create a bold font based on the control's font
using (Font boldFont = new Font(e.SubItem.Font, FontStyle.Bold))
{
// Draw the text in white using the bold font
Rectangle bounds = e.Bounds;
bounds.X += checkBoxSize.Width;
bounds.Y += 2;
e.Graphics.DrawString(e.SubItem.Text, boldFont, e.Item.Selected ? Brushes.White : Brushes.Black, bounds);
}
}
else
{
var bounds = e.Bounds;
bounds.Y += 2;
// Default drawing for other items
if (e.ColumnIndex == 0)
bounds.X += checkBoxSize.Width;
e.Graphics.DrawString(e.SubItem.Text, e.SubItem.Font, Brushes.Black, bounds);
}
}
// Handle drawing of column headers (default handling)
private void StripListView_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
{
e.DrawDefault = true; // Defer to default drawing
}
protected override void OnNotifyMessage(Message m)
{
// Eat the WM_ERASEBKGND message for cleaner painting with less flicker, like Task Manager :-)
if (m.Msg != 0x14)
base.OnNotifyMessage(m);
}
}
}