1

I have a winforms application (C#, .NET 3.5 but eventually migrating to 4.0) which uses a ListView to present attachments (files/web links) in a similar style to windows explorer.

This functionality has been well received by he application users. A request has been made to edxpand this to include sorting the details view by clicking on column headers (same as in windows explorer)

Windows explorer sorting

This is the style of sorting that I'm aiming for (using a triangular glyph to indicate sort direction)

I've come close to achieving this by using the columns ImageKey property.

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";
        }
     }

Unfortunately the image appears to the left of the text, rather than the right.

enter image description here

ColumnHeader TextAlign property is set to Left, there are few other properties available in the designer, none appear to be of any use.

Does anyone know if it's possible to make the image appear to the right of the text while it is left aligned, or is there another approach I will have to use?

One option I've come across is using a unicode glyph in the header text. However, I'd rather avoid this if possible as the unicode glyph does not particularly nice.

Daniel Snowden
  • 177
  • 1
  • 11

1 Answers1

0

The only way I know how to do that is via 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);
EricLaw
  • 56,563
  • 7
  • 151
  • 196
  • 1
    But see http://stackoverflow.com/questions/254129/how-to-i-display-a-sort-arrow-in-the-header-of-a-list-view-column-using-c for an example that mimics Explorer even more closely. – EricLaw Oct 31 '12 at 19:39