• $ cat "

    Unit Testing Selection on a Windows Forms ListView Control

    "

    This is kind of an edge case, but it just stole about two hours of my day, so I thought it might be of interest for someone else who stumbles upon this problem.

    In the application I am currently working on I am subclassing a ListView to make it handle strongly typed tags, and for example directly get a strongly typed instance of the tag of the currently selected item. To test my implementation I programmatically created an instance of my ListView subclass, added items and added an item to the selection using both:

    Item.Selected = true

    and


    listView.SelectedIndices.Add(...)

    The problem was that this had no effect at all on the ListView\'s SelectedIndices and SelectedItems collections.

    I tried doing the same thing on a ListView in one of the forms of my appliation and that worked, but it did not work if I instantiated the ListView directly in the code. After some googeling I finally found a comment to the MSDN documentation on the ListViewItem.Selected Property, saying that the Selected property could not be trusted if the ListView had not been drawn. I did some quick testing myself and confirmed that the problem indeed disappeared if the ListView was drawn.

    So, the solution to the problem was to do something like this:


    [Test]
    public void CanGetSelectedItems()
    {
    // Sadly, this is needed to make the ListView handle selection properly.
    // If the ListView is instantiated directly SelectedIndices, SelectedItems etc
    // do not update when modified.
    var f = new DummyForm(listView);
    f.Show();

    listView.SelectedIndices.Add(0);

    Assert.AreEqual(1, listView.SelectedIndices.Count);

    ICollection<string> items = listView.SelectedItems;

    Assert.AreEqual(1, items.Count);
    Assert.IsTrue(items.Contains(strings[0]));
    }

    private class DummyForm : Form
    {
    public DummyForm(ListView listView)
    {
    this.WindowState = FormWindowState.Minimized;
    this.ShowInTaskbar = false;
    this.Controls.Add(listView);
    }
    }