在ListView中使用Column ImageKey来模拟Windows资源管理器样式排序

时间:2012-10-08 07:48:39

标签: c# winforms listview

我有一个winforms应用程序(C#,.NET 3.5,但最终迁移到4.0),它使用ListView以类似于Windows资源管理器的方式显示附件(文件/ Web链接)。

此功能受到应用程序用户的欢迎。已经请求edxpand,包括通过单击列标题对详细信息视图进行排序(与Windows资源管理器中相同)

Windows explorer sorting

这是我的目标排序方式(使用三角形字形表示排序方向)

通过使用ImageKey属性列,我已经接近实现这一目标。

if (lvAttachments.ListViewItemSorter != null)
     {
        lvAttachments.Sort();

        if (lvwColumnSorter != null)
        {
           if (lvwColumnSorter.Order == System.Windows.Forms.SortOrder.Ascending)
              lvAttachments.Columns[lvwColumnSorter.SortColumn].ImageKey = "sortAsc";
           if (lvwColumnSorter.Order == System.Windows.Forms.SortOrder.Descending)
              lvAttachments.Columns[lvwColumnSorter.SortColumn].ImageKey = "sortDesc";
        }
     }

不幸的是,图片显示在文字的左侧,而不是右侧。

enter image description here

ColumnHeader TextAlign属性设置为Left,设计器中可用的其他属性很少,似乎没有任何用途。

是否有人知道在图片左对齐时是否可以将图片显示在文字的右侧,或者是否还有其他方法需要使用?

我遇到的一个选项是在标题文本中使用unicode字形。但是,如果可能的话,我宁愿避免这种情况,因为unicode字形不是特别好。

1 个答案:

答案 0 :(得分:0)

我知道如何做的唯一方法是通过PInvoke:

    [StructLayoutAttribute(LayoutKind.Sequential)]
    internal struct LV_COLUMN
    {
        public UInt32 mask;
        public Int32 fmt;
        public Int32 cx;
        public String pszText;
        public Int32 cchTextMax;
        public Int32 iSubItem;
        public Int32 iImage;
        public Int32 iOrder;
    }

    [DllImport("User32", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
    internal static extern IntPtr SendLVColMessage(IntPtr hWnd, UInt32 msg, UInt32 wParam, ref LV_COLUMN lParam);

    internal const uint LVCF_FMT = 0x1;
    internal const uint LVCF_IMAGE = 0x10;
    internal const int LVCFMT_IMAGE = 0x800;
    internal const int LVCFMT_BITMAP_ON_RIGHT = 0x1000;

    // Get the old format flags
    col.mask = LVNative.LVCF_FMT;
    LVNative.SendLVColMessage(lvSessions.Handle, LVNative.LVM_GETCOLUMN, (UInt32)iCol, ref col);

    // Set the new format flags
    col.mask = LVNative.LVCF_FMT | LVNative.LVCF_IMAGE;
    col.fmt |= LVNative.LVCFMT_IMAGE | LVNative.LVCFMT_BITMAP_ON_RIGHT;
    col.iImage = (bAscending) ? (int)SessionIcons.SortAscending : (int)SessionIcons.SortDescending;
    LVNative.SendLVColMessage(lvSessions.Handle, LVNative.LVM_SETCOLUMN, (UInt32)iCol, ref col);