使用WinAPI设置ListViewItem的Checked状态 [英] Setting ListViewItem's Checked state using WinAPI

查看:42
本文介绍了使用WinAPI设置ListViewItem的Checked状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码试图用于检查和取消选中列表视图中的项目.在所有内容的下方,检查功能似乎正在运行.问题在于取消选中功能不起作用,并且选中已选中的项目只会使复选框可见,而不会触发选中的事件或取消选中该复选框.我发现的所有内容都告诉我这应该可行,但是我只是无法在这里提出可行的解决方案.谁能解释为什么0x1000没有取消选中项目以及为什么复选框对我不可见?

I have the following code that I am trying to use to check and uncheck items in a list view. Underneath everything, the checking functionality seems to be working. The problem is that the uncheck functionality does not work, and checking the item that is already checked simply makes the check box visible without firing the checked event or unchecking the box. Everything I've found has shown me that this should work, but I am just not able to come up with a working solution here. Can anybody explain why 0x1000 is not unchecking the items and why the check boxes go invisible on me?

谢谢

  public class NativeMethods
  {
    private const int LVM_FIRST = 0x1000;
    private const int LVM_SETITEMSTATE = LVM_FIRST + 43;

    private const int LVIF_STATE = 0x8;

    private const int LVIS_UNCHECKED = 0x1000;
    private const int LVIS_CHECKED = 0x2000;
    private const int LVIS_CHECKEDMASK = 0x3000;

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public struct LVITEM
    {
      public int mask;
      public int iItem;
      public int iSubItem;
      public int state;
      public int stateMask;
      [MarshalAs(UnmanagedType.LPTStr)]
      public string pszText;
      public int cchTextMax;
      public int iImage;
      public IntPtr lParam;
      public int iIndent;
      public int iGroupId;
      public int cColumns;
      public IntPtr puColumns;
    };

    [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
    public static extern IntPtr SendMessageLVItem(IntPtr hWnd, int msg, int wParam, ref LVITEM lvi);

    /// <summary>
    /// Check all rows on the given listview
    /// </summary>
    /// <param name="list">The listview whose items are to be checked</param>
    public static void CheckAllItems(ListView list)
    { // -1 index means all items in the list
      SetItemState(list, -1, LVIS_CHECKED, LVIS_CHECKEDMASK);
    }

    /// <summary>
    /// Uncheck all rows on the given listview
    /// </summary>
    /// <param name="list">The listview whose items are to be unchecked</param>
    public static void UncheckAllItems(ListView list)
    { // -1 index means all items in the list
      SetItemState(list, -1, LVIS_UNCHECKED, LVIS_CHECKEDMASK);
    }

    /// <summary>
    /// Set the item state on the given item
    /// </summary>
    /// <param name="list">The listview whose item's state is to be changed</param>
    /// <param name="itemIndex">The index of the item to be changed</param>
    /// <param name="mask">Which bits of the value are to be set?</param>
    /// <param name="value">The value to be set</param>
    public static void SetItemState(ListView list, int itemIndex, int mask, int value)
    {
      LVITEM lvItem = new LVITEM();
      lvItem.mask = LVIF_STATE;
      lvItem.stateMask = mask;
      lvItem.state = value;
      SendMessageLVItem(list.Handle, LVM_SETITEMSTATE, itemIndex, ref lvItem);
    }
  }

编辑

我在这里对行为进行了双重检查,当我为未选中的项目选择全部选中",为选中的项目选择全部取消选中"时,会发生这种情况.它们变得不可见.全部取消选中"不会将项目从已选中"更改为未选中",但显然是正确的状态,因为选择全部未选中"的未选中全部"不会导致任何更改.当所有项目都已选中时,全选"也是如此.

I double checked behavior here, and this happens when I select "Check All" for items that are unchecked and "Uncheck All" for items that are checked. They become invisible. "Uncheck All" does not change the item from checked to unchecked, but it is clearly the correct state, as selecting "Unselect All" with no items checked results in no changes at all. The same is true for "Select All" when all items are checked already.

推荐答案

对于此处的错误,我深表歉意.我更改了掩码和值,所以这是正确的解决方案:

I apologize for my error here. I switched the mask and value around, so here is the correct solution:

public class NativeMethods
{
  private const int LVM_FIRST = 0x1000;
  private const int LVM_SETITEMSTATE = LVM_FIRST + 43;

  private const int LVIS_UNCHECKED = 0x1000;
  private const int LVIS_CHECKED = 0x2000;
  private const int LVIS_STATEIMAGEMASK = 0x3000;

  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
  public struct LVITEM
  {
    public int mask;
    public int iItem;
    public int iSubItem;
    public int state;
    public int stateMask;
    [MarshalAs(UnmanagedType.LPTStr)]
    public string pszText;
    public int cchTextMax;
    public int iImage;
    public IntPtr lParam;
    public int iIndent;
    public int iGroupId;
    public int cColumns;
    public IntPtr puColumns;
  };

  [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
  public static extern IntPtr SendMessageLVItem(IntPtr hWnd, int msg, int wParam, ref LVITEM lvi);

  /// <summary>
  /// Select all rows on the given listview
  /// </summary>
  /// <param name="list">The listview whose items are to be selected</param>
  public static void CheckAllItems(ListView list)
  {
    SetItemState(list, -1, LVIS_STATEIMAGEMASK, LVIS_CHECKED);
  }

  /// <summary>
  /// Deselect all rows on the given listview
  /// </summary>
  /// <param name="list">The listview whose items are to be deselected</param>
  public static void UncheckAllItems(ListView list)
  {
    SetItemState(list, -1, LVIS_STATEIMAGEMASK, LVIS_UNCHECKED);
  }

  /// <summary>
  /// Set the item state on the given item
  /// </summary>
  /// <param name="list">The listview whose item's state is to be changed</param>
  /// <param name="itemIndex">The index of the item to be changed</param>
  /// <param name="mask">Which bits of the value are to be set?</param>
  /// <param name="value">The value to be set</param>
  public static void SetItemState(ListView list, int itemIndex, int mask, int value)
  {
    LVITEM lvItem = new LVITEM();
    lvItem.stateMask = mask;
    lvItem.state = value;
    SendMessageLVItem(list.Handle, LVM_SETITEMSTATE, itemIndex, ref lvItem);
  }
}

这篇关于使用WinAPI设置ListViewItem的Checked状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆