I wasn\'t able to find an answer anywhere about this seemingly simple topic: is it possible to align text of a single subitem in a WinForms ListView control?
Put the ListView control on form and name it "listV1" and add and edit 4 columns. Also define one Index. Then, format column "0" without the header and with Width=0. That way column 0 will be invisible. Then you can format other columns as you wish (left, center,right) which are all visible.
ListView listV1 = new ListView();
uint Index = 0;
string[] Split_Message = Some_Message.Split(','); // split it to comma...
ListViewItem L = new ListViewItem(""); //... to column "0" assign empty string...
L.SubItems.Add(Index.ToString() + "."); //... than fill the first fild in the row. It is number converted to string...
L.SubItems.Add(Split_Message[0]); //... then first string from buffer...
L.SubItems.Add(Split_Message[1]); //... again, second string from buffer etc. ...
listV1.Items.Add(L); //... and at the end write all of this into the first row.
Indexx++; // Next number.
For future reference, here's how I solved it:
// Make owner-drawn to be able to give different alignments to single subitems
lvResult.OwnerDraw = true;
...
// Handle DrawSubItem event
private void lvResult_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
{
// This is the default text alignment
TextFormatFlags flags = TextFormatFlags.Left;
// Align text on the right for the subitems after row 11 in the
// first column
if (e.ColumnIndex == 0 && e.Item.Index > 11)
{
flags = TextFormatFlags.Right;
}
e.DrawText(flags);
}
// Handle DrawColumnHeader event
private void lvResult_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
{
// Draw the column header normally
e.DrawDefault = true;
e.DrawBackground();
e.DrawText();
}
It was necessary to handle the DrawColumnHeader, otherwise no text or column separators would be drawn.
example :
listView1.Columns[1].TextAlign = HorizontalAlignment.Right;
will set Column's "1" alignment to right
The "ColumnHeader" class has a "TextAlign" property that will change the alignment for all subitems in the column. If you need something more fancy you could always use the "DrawSubItem" event and make it owner drawn.
Building on the answer by @Fueled, here's what I did to use the column header alignment:
protected override void OnDrawSubItem( DrawListViewSubItemEventArgs e )
{
// Match the subitem alignment to the column header alignment
TextFormatFlags flags = TextFormatFlags.Left;
switch ( this.Columns[ e.ColumnIndex ].TextAlign )
{
case HorizontalAlignment.Right:
flags = TextFormatFlags.Right;
break;
case HorizontalAlignment.Center:
flags = TextFormatFlags.HorizontalCenter;
break;
}
e.DrawText( flags );
}
Note: Due to a limitation of the underlying native ListView control (living in comctl32.dll), the first column cannot be aligned. It will be always aligned left. The second limitation is when you custom draw (custom draw subitems): when you enable column reordering, the text of the first column is NOT reordered correctly. I solved this limitation (would not call it a bug, because the listview supports many list styles and the internal data structure of a list view is a tree like one) by not allowing to reorder the first column, which in most cases is no problem, because you'll use some sort of key for the first column like number or something similar.