【问题标题】:How can I remove the checkboxes from individual items in a ListView control?如何从 ListView 控件中的单个项目中删除复选框?
【发布时间】:2011-08-21 12:32:40
【问题描述】:

我有一个包含“名称”、“预期”、“总计”列的 ListView,并且我想在末尾添加另一列“重新计数”。理想情况下,仅当“预期”值大于“总计”值时,“重新计数”列才会有一个复选框。

到目前为止,我已经获得了带有列的 ListView,并且可以在左侧添加一个复选框,但该复选框不在列标题下(尽管我可能可以在其中放置另一个没有值的列来解决那)并且它在所有记录中。

有人知道我还能做什么吗?

【问题讨论】:

  • 嗯,ListBox 没有列。 ListView 可以,但这似乎不是您正在使用的。能给我们看一下控件的截图吗?
  • 啊,你是对的,它是一个列表视图。抱歉,我对任何与 Windows 窗体有关的事情都束手无策

标签: .net vb.net winforms listview checkbox


【解决方案1】:

这实际上实现起来相对简单,前提是您愿意忍受 P/Invoke 的苦差事来访问内置于本机 Windows 控件中但不被 .NET FW 公开的功能。

我演示了in my answer here 如何使用 TreeView 控件完成完全相同的操作,并且考虑到 ListView 与 TreeView 的相似程度,使用与一个列表视图。

这是所需的所有代码(确保您已为 System.Runtime.InteropServices 命名空间添加了 Imports 声明):

' P/Invoke declarations
Private Const LVIF_STATE As Integer = &H8
Private Const LVIS_STATEIMAGEMASK As Integer = &HF000
Private Const LVM_FIRST As Integer = &H1000
Private Const LVM_SETITEM As Integer = LVM_FIRST + 76

<StructLayout(LayoutKind.Sequential, Pack:=8, CharSet:=CharSet.Auto)> _
Private Structure LVITEM
   Public mask As Integer
   Public iItem As Integer
   Public iSubItem As Integer
   Public state As Integer
   Public stateMask As Integer
   <MarshalAs(UnmanagedType.LPTStr)> _
   Public lpszText As String
   Public cchTextMax As Integer
   Public iImage As Integer
   Public lParam As IntPtr
End Structure

<DllImport("user32.dll", CharSet:=CharSet.Auto)> _
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As IntPtr, ByRef lParam As LVITEM) As IntPtr
End Function

''' <summary>
''' Hides the checkbox for the specified item in a ListView control.
''' </summary>
Private Sub HideCheckBox(ByVal lvw As ListView, ByVal item As ListViewItem)
   Dim lvi As LVITEM = New LVITEM()
   lvi.iItem = item.Index
   lvi.mask = LVIF_STATE
   lvi.stateMask = LVIS_STATEIMAGEMASK
   lvi.state = 0
   SendMessage(lvw.Handle, LVM_SETITEM, IntPtr.Zero, lvi)
End Sub

然后你可以像这样简单地调用上面的方法:

Private Sub btnHideCheckForSelected_Click(ByVal sender As Object, ByVal e As EventArgs)
   ' Hide the checkbox next to the currently selected ListViewItem
   HideCheckBox(myListView, myListView.SelectedItems(0))
End Sub

制作看起来有点像这样的东西(在为番茄和黄瓜项目单击“隐藏检查”按钮后):

     

【讨论】:

  • 看起来不错,但我收到错误 can't find pinvoke dll user32.dll 并且找不到要引用的 user32.dll 文件。还有其他我要参考的东西吗?顺便说一句,谢谢:)
  • @Harold: Hrm... 你在 Linux 上运行 Mono 吗?该代码假定您正在运行 Windows。
  • 我在 Windows 7 上的紧凑型移动框架上运行,Visual Studio 2008
  • @Harold:我明白了。我对紧凑框架一无所知。我原以为user32.dll 仍然存在,但我不能确定。由于紧凑框架针对不同的设备,它不支持完整框架为完整版 Windows 所做的一切。
  • 其实according to this page,貌似紧凑的框架将user32.dll重命名为coredll.dll。不管出于什么荒谬的原因。您可以尝试将 P/Invoke 声明更改为该声明。但是仍然不能保证它会起作用。 ListView 控件在底层可能有所不同。我假设完整的 Win32 API 的详细信息。
【解决方案2】:

以下是 C# 版本。

    private void HideCheckbox(ListView lvw, ListViewItem item)
    {
        var lviItem = new LVITEM();
        lviItem.iItem = item.Index;
        lviItem.mask = LVIF_STATE;
        lviItem.stateMask = LVIS_STATEIMAGEMASK;
        lviItem.state = 0;
        SendMessage(lvw.Handle, LVM_SETITEM, IntPtr.Zero, ref lviItem);
    }

    private const int LVIF_STATE = 0x8;
    private const int LVIS_STATEIMAGEMASK = 0xF000;
    private const int LVM_FIRST = 0x1000;
    private const int LVM_SETITEM = LVM_FIRST + 76;

    // suppress warnings for interop
#pragma warning disable 0649
    private struct LVITEM
    {
        public int mask;
        public int iItem;
        public int iSubItem;
        public int state;
        public int stateMask;
        [MarshalAs(UnmanagedType.LPTStr)]
        public String lpszText;
        public int cchTextMax;
        public int iImage;
        public IntPtr iParam;
    }
#pragma warning restore 0649

    [DllImport("user32.dll")]
    private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam,  ref LVITEM lParam);

    private void button1_Click(object sender, EventArgs e)
    {
        HideCheckbox(listView1, listView1.SelectedItems[0]);
    }    

【讨论】:

  • 谢谢,这对我有帮助。注意:项目添加到 ListView 后,需要调用 HideCheckbox 方法。
猜你喜欢
  • 2017-07-25
  • 1970-01-01
  • 2012-02-19
  • 1970-01-01
  • 1970-01-01
  • 2015-06-26
  • 2019-07-07
  • 1970-01-01
  • 2011-05-27
相关资源
最近更新 更多