如何修复 ListView 中的控件重影问题?

Posted

技术标签:

【中文标题】如何修复 ListView 中的控件重影问题?【英文标题】:How do I fix control ghosting issue in ListView? 【发布时间】:2021-04-27 10:09:10 【问题描述】:

我有一个 ListView 控件,我想在 ListView 的左上角添加一个复选框。

我正在使用的添加 CheckBox 控件的解决方案是这样的:

Me.ListViewCustom1.Controls.Add(CheckBoxControl);
Me.CheckBoxControl.Location = new Point(3, 5);

我遇到的问题是 ListView 滚动。复选框看起来都被弄脏了。我一直在网上寻找解决方案,但我真的找不到可以解决这个问题的东西。

这是控件的显示方式:

我特此在这种复杂的情况下寻求帮助。

【问题讨论】:

How to add a Checkbox to a ListView column header? 我真的看到了那个帖子。为复选框添加专用列的想法很聪明,但我想在没有新列的情况下解决问题。你觉得有可能吗? See here 捕获滚动事件;那么也许刷新会有所帮助.. 我也遇到过这个解决方案的问题。因为我设置的位置不遵循“列”。刷新后,复选框出现在与第一列不相关的位置:/ 【参考方案1】:

假设您不想要我在linked post 中使用的选项,您可以解决此问题的另一种方法是将CheckBox 添加到ListView 的标题中。

使用SendMessage你可以发送LVM_GETHEADER消息到listview控件并获取header的句柄,然后SetParent会帮助你将header设置为checkbox的父级:

const int LVM_GETHEADER = 0x1000 + 31;
[DllImport("user32.dll")]
static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
private void Form1_Load(object sender, EventArgs e)

    var header = SendMessage(listView1.Handle, LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero);
    var checkBox = new CheckBox()
    
        AutoSize = true,
        Text = "",
        Location = new Point(3, 5)
    ;
    this.listView1.Controls.Add(checkBox);
    SetParent(checkBox.Handle, header);

这就是你得到的:

显然,我在列标题的文本之前添加了一些额外的空格,以便为复选框腾出空间。

【讨论】:

这看起来很有希望!我会尽快看一下,然后我会将您的答案标记为正确答案。谢谢你:) 我已经测试了答案。复选框出现,但在将鼠标悬停在第一列后立即隐藏。 @PashaZakharuk 它在我的测试中正常工作。您可能已经将自己的解决方案与这篇文章混合在一起。查看更新后的屏幕截图。 你是对的。我认为你的答案是正确的。我创建了一个全新的控件,它运行良好!谢谢! 酷!我的荣幸:)

以上是关于如何修复 ListView 中的控件重影问题?的主要内容,如果未能解决你的问题,请参考以下文章

公共控件Listview

如何修复动态适配器包装器 Android 中的 notifyDataSetChanged/ListView 问题

如何修复 javafx 中的渲染错误(ComboBox、ListView)

如何访问ListView EditItemTemplate中的控件

如何在 C#中的listView 控件中显示图片?

如何在 C#中的listView 控件中显示图片?