Skip to content

Commit bc59bd4

Browse files
Improve ListView DarkMode.
1 parent 03e386c commit bc59bd4

File tree

1 file changed

+103
-57
lines changed
  • src/System.Windows.Forms/System/Windows/Forms/Controls/ListView

1 file changed

+103
-57
lines changed

src/System.Windows.Forms/System/Windows/Forms/Controls/ListView/ListView.cs

Lines changed: 103 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1846,7 +1846,7 @@ public View View
18461846

18471847
if (IsHandleCreated && _viewStyle == View.Details)
18481848
{
1849-
ApplyColumnHeaderDarkModeOnDemand();
1849+
ApplyDarkModeOnDemand();
18501850
}
18511851

18521852
UpdateListViewItemsLocations();
@@ -4537,8 +4537,6 @@ protected override void OnHandleCreated(EventArgs e)
45374537
PInvokeCore.SendMessage(this, PInvoke.CCM_SETVERSION, (WPARAM)5);
45384538
}
45394539

4540-
ApplyColumnHeaderDarkModeOnDemand();
4541-
45424540
UpdateExtendedStyles();
45434541
RealizeProperties();
45444542
PInvokeCore.SendMessage(this, PInvoke.LVM_SETBKCOLOR, (WPARAM)0, (LPARAM)BackColor);
@@ -4599,6 +4597,7 @@ protected override void OnHandleCreated(EventArgs e)
45994597
}
46004598

46014599
int columnCount = _columnHeaders is null ? 0 : _columnHeaders.Length;
4600+
46024601
if (columnCount > 0)
46034602
{
46044603
int[] indices = new int[columnCount];
@@ -4644,6 +4643,7 @@ protected override void OnHandleCreated(EventArgs e)
46444643
// When the handle is recreated, update the SavedCheckedItems.
46454644
// It is possible some checked items were added to the list view while its handle was null.
46464645
_savedCheckedItems = null;
4646+
46474647
if (!CheckBoxes && !VirtualMode)
46484648
{
46494649
for (int i = 0; i < Items.Count; i++)
@@ -4654,21 +4654,48 @@ protected override void OnHandleCreated(EventArgs e)
46544654
}
46554655
}
46564656
}
4657+
4658+
if (!RecreatingHandle)
4659+
{
4660+
ApplyDarkModeOnDemand();
4661+
}
46574662
}
46584663

4659-
private void ApplyColumnHeaderDarkModeOnDemand()
4664+
#pragma warning disable WFO5001
4665+
private void ApplyDarkModeOnDemand()
46604666
{
4661-
#pragma warning disable WFO5001 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
46624667
if (Application.IsDarkModeEnabled)
46634668
{
4664-
_ = PInvoke.SetWindowTheme(HWND, $"{DarkModeIdentifier}_{ExplorerThemeIdentifier}", null);
4669+
// Enable double buffering when in dark mode to reduce flicker.
4670+
uint exMask = PInvoke.LVS_EX_ONECLICKACTIVATE | PInvoke.LVS_EX_TWOCLICKACTIVATE |
4671+
PInvoke.LVS_EX_TRACKSELECT | PInvoke.LVS_EX_UNDERLINEHOT |
4672+
PInvoke.LVS_EX_ONECLICKACTIVATE | PInvoke.LVS_EX_HEADERDRAGDROP |
4673+
PInvoke.LVS_EX_CHECKBOXES | PInvoke.LVS_EX_FULLROWSELECT |
4674+
PInvoke.LVS_EX_GRIDLINES | PInvoke.LVS_EX_INFOTIP | PInvoke.LVS_EX_DOUBLEBUFFER;
4675+
4676+
uint exStyle = BuildExStyleInternal();
4677+
exStyle |= PInvoke.LVS_EX_DOUBLEBUFFER;
4678+
4679+
PInvokeCore.SendMessage(
4680+
this,
4681+
PInvoke.LVM_SETEXTENDEDLISTVIEWSTYLE,
4682+
(WPARAM)exMask,
4683+
(LPARAM)exStyle);
4684+
4685+
// Apply dark mode theme to the ListView
4686+
_ = PInvoke.SetWindowTheme(
4687+
HWND,
4688+
$"{DarkModeIdentifier}_{ExplorerThemeIdentifier}",
4689+
null);
46654690

46664691
// Get the ListView's ColumnHeader handle:
46674692
HWND columnHeaderHandle = (HWND)PInvokeCore.SendMessage(this, PInvoke.LVM_GETHEADER, (WPARAM)0, (LPARAM)0);
4693+
4694+
// Apply dark mode theme to the ColumnHeader
46684695
PInvoke.SetWindowTheme(columnHeaderHandle, $"{DarkModeIdentifier}_{ItemsViewThemeIdentifier}", null);
46694696
}
4670-
#pragma warning restore WFO5001
46714697
}
4698+
#pragma warning restore WFO5001
46724699

46734700
protected override void OnHandleDestroyed(EventArgs e)
46744701
{
@@ -5622,68 +5649,86 @@ private void UpdateColumnWidths(ColumnHeaderAutoResizeStyle headerAutoResize)
56225649
}
56235650
}
56245651

5625-
protected void UpdateExtendedStyles()
5652+
private uint BuildExStyleInternal()
56265653
{
5627-
if (IsHandleCreated)
5654+
if (!IsHandleCreated)
56285655
{
5629-
uint exStyle = 0;
5630-
uint exMask = PInvoke.LVS_EX_ONECLICKACTIVATE | PInvoke.LVS_EX_TWOCLICKACTIVATE |
5631-
PInvoke.LVS_EX_TRACKSELECT | PInvoke.LVS_EX_UNDERLINEHOT |
5632-
PInvoke.LVS_EX_ONECLICKACTIVATE | PInvoke.LVS_EX_HEADERDRAGDROP |
5633-
PInvoke.LVS_EX_CHECKBOXES | PInvoke.LVS_EX_FULLROWSELECT |
5634-
PInvoke.LVS_EX_GRIDLINES | PInvoke.LVS_EX_INFOTIP | PInvoke.LVS_EX_DOUBLEBUFFER;
5656+
return 0;
5657+
}
56355658

5636-
switch (_activation)
5637-
{
5638-
case ItemActivation.OneClick:
5639-
exStyle |= PInvoke.LVS_EX_ONECLICKACTIVATE;
5640-
break;
5641-
case ItemActivation.TwoClick:
5642-
exStyle |= PInvoke.LVS_EX_TWOCLICKACTIVATE;
5643-
break;
5644-
}
5659+
uint exStyle = 0;
56455660

5646-
if (AllowColumnReorder)
5647-
{
5648-
exStyle |= PInvoke.LVS_EX_HEADERDRAGDROP;
5649-
}
5661+
switch (_activation)
5662+
{
5663+
case ItemActivation.OneClick:
5664+
exStyle |= PInvoke.LVS_EX_ONECLICKACTIVATE;
5665+
break;
5666+
case ItemActivation.TwoClick:
5667+
exStyle |= PInvoke.LVS_EX_TWOCLICKACTIVATE;
5668+
break;
5669+
}
56505670

5651-
if (CheckBoxes)
5652-
{
5653-
exStyle |= PInvoke.LVS_EX_CHECKBOXES;
5654-
}
5671+
if (AllowColumnReorder)
5672+
{
5673+
exStyle |= PInvoke.LVS_EX_HEADERDRAGDROP;
5674+
}
56555675

5656-
if (DoubleBuffered)
5657-
{
5658-
exStyle |= PInvoke.LVS_EX_DOUBLEBUFFER;
5659-
}
5676+
if (CheckBoxes)
5677+
{
5678+
exStyle |= PInvoke.LVS_EX_CHECKBOXES;
5679+
}
56605680

5661-
if (FullRowSelect)
5662-
{
5663-
exStyle |= PInvoke.LVS_EX_FULLROWSELECT;
5664-
}
5681+
if (DoubleBuffered)
5682+
{
5683+
exStyle |= PInvoke.LVS_EX_DOUBLEBUFFER;
5684+
}
56655685

5666-
if (GridLines)
5667-
{
5668-
exStyle |= PInvoke.LVS_EX_GRIDLINES;
5669-
}
5686+
if (FullRowSelect)
5687+
{
5688+
exStyle |= PInvoke.LVS_EX_FULLROWSELECT;
5689+
}
56705690

5671-
if (HoverSelection)
5672-
{
5673-
exStyle |= PInvoke.LVS_EX_TRACKSELECT;
5674-
}
5691+
if (GridLines)
5692+
{
5693+
exStyle |= PInvoke.LVS_EX_GRIDLINES;
5694+
}
56755695

5676-
if (HotTracking)
5677-
{
5678-
exStyle |= PInvoke.LVS_EX_UNDERLINEHOT;
5679-
}
5696+
if (HoverSelection)
5697+
{
5698+
exStyle |= PInvoke.LVS_EX_TRACKSELECT;
5699+
}
56805700

5681-
if (ShowItemToolTips)
5682-
{
5683-
exStyle |= PInvoke.LVS_EX_INFOTIP;
5684-
}
5701+
if (HotTracking)
5702+
{
5703+
exStyle |= PInvoke.LVS_EX_UNDERLINEHOT;
5704+
}
5705+
5706+
if (ShowItemToolTips)
5707+
{
5708+
exStyle |= PInvoke.LVS_EX_INFOTIP;
5709+
}
5710+
5711+
return exStyle;
5712+
}
5713+
5714+
protected void UpdateExtendedStyles()
5715+
{
5716+
if (IsHandleCreated)
5717+
{
5718+
uint exMask = PInvoke.LVS_EX_ONECLICKACTIVATE | PInvoke.LVS_EX_TWOCLICKACTIVATE |
5719+
PInvoke.LVS_EX_TRACKSELECT | PInvoke.LVS_EX_UNDERLINEHOT |
5720+
PInvoke.LVS_EX_ONECLICKACTIVATE | PInvoke.LVS_EX_HEADERDRAGDROP |
5721+
PInvoke.LVS_EX_CHECKBOXES | PInvoke.LVS_EX_FULLROWSELECT |
5722+
PInvoke.LVS_EX_GRIDLINES | PInvoke.LVS_EX_INFOTIP | PInvoke.LVS_EX_DOUBLEBUFFER;
5723+
5724+
uint exStyle = BuildExStyleInternal();
5725+
5726+
PInvokeCore.SendMessage(
5727+
this,
5728+
PInvoke.LVM_SETEXTENDEDLISTVIEWSTYLE,
5729+
(WPARAM)exMask,
5730+
(LPARAM)exStyle);
56855731

5686-
PInvokeCore.SendMessage(this, PInvoke.LVM_SETEXTENDEDLISTVIEWSTYLE, (WPARAM)exMask, (LPARAM)exStyle);
56875732
Invalidate();
56885733
}
56895734
}
@@ -6405,6 +6450,7 @@ internal void RecreateHandleInternal()
64056450
}
64066451

64076452
RecreateHandle();
6453+
ApplyDarkModeOnDemand();
64086454
}
64096455

64106456
private unsafe void WmReflectNotify(ref Message m)

0 commit comments

Comments
 (0)