Skip to content

Commit 911126f

Browse files
author
Simon Zhao (BEYONDSOFT CONSULTING INC)
committed
Fix issue 11956 in ListView
1 parent 30e2642 commit 911126f

1 file changed

Lines changed: 79 additions & 0 deletions

File tree

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

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

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ public partial class ListView : Control
113113
private ImageList? _imageListSmall;
114114
private ImageList? _imageListState;
115115
private ImageList? _imageListGroup;
116+
private ImageList? _darkModeStateImageList;
116117

117118
private MouseButtons _downButton;
118119
private int _itemCount;
@@ -3066,6 +3067,9 @@ protected override void Dispose(bool disposing)
30663067
DetachGroupImageListHandlers();
30673068
_imageListGroup = null;
30683069

3070+
_darkModeStateImageList?.Dispose();
3071+
_darkModeStateImageList = null;
3072+
30693073
// Remove any ColumnHeaders contained in this control
30703074
if (_columnHeaders is not null)
30713075
{
@@ -4703,9 +4707,84 @@ private void ApplyDarkModeOnDemand()
47034707
columnHeaderHandle,
47044708
$"{DarkModeIdentifier}_{ItemsViewThemeIdentifier}",
47054709
null);
4710+
4711+
if (CheckBoxes)
4712+
{
4713+
UpdateDarkModeCheckBoxImages();
4714+
}
4715+
}
4716+
}
4717+
4718+
private void UpdateDarkModeCheckBoxImages()
4719+
{
4720+
if (_imageListState is not null || !CheckBoxes || !IsHandleCreated)
4721+
{
4722+
return;
4723+
}
4724+
4725+
_darkModeStateImageList?.Dispose();
4726+
4727+
int size = ScaleHelper.ScaleToInitialSystemDpi(16);
4728+
4729+
ImageList imageList = new()
4730+
{
4731+
ImageSize = new Size(size, size),
4732+
ColorDepth = ColorDepth.Depth32Bit,
4733+
TransparentColor = Color.Transparent
4734+
};
4735+
4736+
imageList.Images.Add(CreateDarkModeCheckBoxBitmap(isChecked: false, size));
4737+
imageList.Images.Add(CreateDarkModeCheckBoxBitmap(isChecked: true, size));
4738+
4739+
// Ensure the checkbox extended style is active before assigning our custom state imagelist,
4740+
// otherwise the style refresh may overwrite the list with the default light-themed images.
4741+
ForceCheckBoxUpdate();
4742+
4743+
PInvokeCore.SendMessage(
4744+
this,
4745+
PInvoke.LVM_SETIMAGELIST,
4746+
(WPARAM)PInvoke.LVSIL_STATE,
4747+
(LPARAM)imageList.Handle);
4748+
4749+
_darkModeStateImageList = imageList;
4750+
4751+
if (VirtualMode)
4752+
{
4753+
return;
4754+
}
4755+
4756+
if (Items.Count > 0)
4757+
{
4758+
const LIST_VIEW_ITEM_STATE_FLAGS stateMask = LIST_VIEW_ITEM_STATE_FLAGS.LVIS_STATEIMAGEMASK;
4759+
4760+
for (int i = 0; i < Items.Count; i++)
4761+
{
4762+
bool isChecked = Items[i].Checked;
4763+
int stateIndex = isChecked ? 2 : 1;
4764+
4765+
SetItemState(i, (LIST_VIEW_ITEM_STATE_FLAGS)(stateIndex << 12), stateMask);
4766+
}
4767+
4768+
PInvokeCore.SendMessage(
4769+
this,
4770+
PInvoke.LVM_REDRAWITEMS,
4771+
(WPARAM)0,
4772+
(LPARAM)(Items.Count - 1));
47064773
}
47074774
}
47084775

4776+
private Bitmap CreateDarkModeCheckBoxBitmap(bool isChecked, int size)
4777+
{
4778+
Bitmap bitmap = new(size, size);
4779+
4780+
using Graphics graphics = Graphics.FromImage(bitmap);
4781+
graphics.Clear(Color.Transparent);
4782+
CheckBoxState state = isChecked ? CheckBoxState.CheckedNormal : CheckBoxState.UncheckedNormal;
4783+
CheckBoxRenderer.DrawCheckBoxWithVisualStyles(graphics, new Point(0, 0), state, HWNDInternal);
4784+
4785+
return bitmap;
4786+
}
4787+
47094788
protected override void OnHandleDestroyed(EventArgs e)
47104789
{
47114790
// don't save the list view items state when in virtual mode : it is the responsibility of the

0 commit comments

Comments
 (0)