Select subitem in Listview and change value

Joshua Gilman picture Joshua Gilman · Feb 23, 2014 · Viewed 12.2k times · Source

I have a listview in the "details" mode that looks something like:

#################
Name  #  Property
#################
#Itm1 # Subitm1
#Itm2 # Subitm2
#################

Very simple, but the problem I am running into is I cannot select "Subitm1" in the list at runtime. I can select and highlight every item in the first column, but clicking on any item in the second column does nothing (I would expect it to highlight the item like in the first column).

Specifically, I'm trying to add the ability for a user to be able to double-click a sub-item and change it's value directly at the listview. Is there a specific setting I'm missing here?

Answer

Dmitry picture Dmitry · Feb 23, 2014

If you want to select the whole row when subitem was clicked, try to use FullRowSelect property of ListView. To handle double-click on a subitem, try this:

private void listView1_MouseDoubleClick(object sender, MouseEventArgs e)
{
    ListViewHitTestInfo hit = listView1.HitTest(e.Location);
    // Use hit.Item
    // Use hit.SubItem
}

If you want allow end-user to edit subitem's text at the listview, I'm afraid the easiest way is to use Grid control. Alternative way is to try something like this:

private readonly TextBox txt = new TextBox { BorderStyle = BorderStyle.FixedSingle, Visible = false };

public Form1()
{
    InitializeComponent();
    listView1.Controls.Add(txt);
    listView1.FullRowSelect = true;
    txt.Leave += (o, e) => txt.Visible = false;
}

private void listView1_MouseDoubleClick(object sender, MouseEventArgs e)
{
    ListViewHitTestInfo hit = listView1.HitTest(e.Location);

    Rectangle rowBounds = hit.SubItem.Bounds;
    Rectangle labelBounds = hit.Item.GetBounds(ItemBoundsPortion.Label);
    int leftMargin = labelBounds.Left - 1;
    txt.Bounds = new Rectangle(rowBounds.Left + leftMargin, rowBounds.Top, rowBounds.Width - leftMargin - 1, rowBounds.Height);
    txt.Text = hit.SubItem.Text;
    txt.SelectAll();
    txt.Visible = true;
    txt.Focus();
}