Insertion Mark

Insertion mark is a line showing location between items. Better ListView support displaying the insertion mark on various locations with support for groups and item hierarchy:

The basic usage of insertion mark is the same as in regular .NET ListView. Setting InsertionMark property using one of these constructors will give you the classic insertion mark:

The last constructor has an extra parameter enabled which adjusts insertion mark color slightly (giving it alpha transparency) to be displayed in an inactive or disabled state.

There are also more general constructors for displaying insertion mark on arbitrary location in item hierarchy and on groups:

Instead of index, there is an insertionLocation parameter.

Insertion Locations

The BetterListViewInsertionLocation type can describe any location in item hierarchy and on groups. The location consists of three properties:

Sample Source Code

The following sample shows how to display insertion mark according to current mouse position (see Hit Test).

C#

this.listView.BeginUpdate();

// create groups with items and child items
BetterListViewGroup groupRecent = new BetterListViewGroup("Recent Items");

groupRecent.Items.AddRange(
    new[]
    {
        "Ming Dynasty Vase",
        "Collection of Rembrandt",
        "Photos from Prokudin Gorskij"
    });

groupRecent.Items[1].ChildItems.AddRange(
    new[]
    {
        "The Night Watch",
        "Belshazzar's Feast"
    });

BetterListViewGroup groupArchived = new BetterListViewGroup("Archived Items");

groupArchived.Items.AddRange(
    new[]
    {
        "Statue of Zeus",
        "Rare pens from Hamburg and Dresden"
    });

this.listView.Groups.AddRange(
    new[]
    {
        groupRecent,
        groupArchived
    });

// set custom color for the insertion mark
this.listView.ColorInsertionMark = Color.DarkGreen;
// make the groups visible
this.listView.ShowGroups = true;

this.listView.EndUpdate();

// this will set insertion mark every time hit test changes
this.listView.HitTestChanged += ListViewHitTestChanged;

Visual Basic

ListView.BeginUpdate()

' create groups with items and child items
Dim groupRecent As New BetterListViewGroup("Recent Items")

groupRecent.Items.AddRange(
    New String() {
        "Ming Dynasty Vase",
        "Collection of Rembrandt",
        "Photos from Prokudin Gorskij"
                 })

groupRecent.Items(1).ChildItems.AddRange(
    New String() {
        "The Night Watch",
        "Belshazzar's Feast"
                 })

Dim groupArchived As New BetterListViewGroup("Archived Items")

groupArchived.Items.AddRange(
    New String() {
        "Statue of Zeus",
        "Rare pens from Hamburg and Dresden"
                 })

ListView.Groups.AddRange(New BetterListViewGroup() {groupRecent, groupArchived})

' set custom color for the insertion mark
ListView.ColorInsertionMark = Color.DarkGreen
' make the groups visible
ListView.ShowGroups = True

ListView.EndUpdate()

' this will set insertion mark every time hit test changes
AddHandler ListView.HitTestChanged, AddressOf ListViewHitTestChanged

The HitTestInfoChanged event handler determines the actual insertion mark location and sets it:

C#

void ListViewHitTestChanged(object sender, BetterListViewHitTestChangedEventArgs eventArgs)
{
    // get current hit test information
    BetterListViewHitTestInfo hitTestInfo = eventArgs.HitTestInfoNew;

    // get address and drop part to assembly an insertion mark location
    BetterListViewAddress address;
    BetterListViewDropPart dropPart;

    if (hitTestInfo.Item != null)
    {
        // the mouse cursor is located on item
        address = hitTestInfo.Item.Address;

        if ((hitTestInfo.ItemPart & BetterListViewHitPart.VCenter) == BetterListViewHitPart.VCenter)
        {
            // the mouse cursor is located in the centre of the item - the insertion mark will point inside the item
            dropPart = BetterListViewDropPart.Inside;
        }
        else
        {
            // the mouse cursor is located on other parts of the item - the insertion mark will point before on after the item
            dropPart = (((hitTestInfo.ItemPart & BetterListViewHitPart.Bottom) == BetterListViewHitPart.Bottom)
                            ? BetterListViewDropPart.After
                            : BetterListViewDropPart.Before);
        }
    }
    else if (
        hitTestInfo.Group != null)
    {
        // the mouse cursor is located on group
        address = hitTestInfo.Group.Address;
        dropPart = BetterListViewDropPart.Inside; //NOTE: only Inside is allowed as drop part on groups
    }
    else
    {
        // the mouse cursor is not located on item nor group
        address = null;
        dropPart = BetterListViewDropPart.Undefined;
    }

    if (address != null)
    {
        // set insertion mark on the constructed location
        this.listView.InsertionMark = new BetterListViewInsertionMark(new BetterListViewInsertionLocation(address, dropPart));
    }
    else
    {
        // reset insertion mark
        this.listView.InsertionMark = BetterListViewInsertionMark.Empty;
    }
}

Visual Basic

Sub ListViewHitTestChanged(ByVal sender As Object, ByVal eventArgs As BetterListViewHitTestChangedEventArgs)

    ' get current hit test information
    Dim hitTestInfo As BetterListViewHitTestInfo = eventArgs.HitTestInfoNew

    ' get address and drop part to assembly an insertion mark location
    Dim address As BetterListViewAddress
    Dim dropPart As BetterListViewDropPart

    If hitTestInfo.Item IsNot Nothing Then

        ' the mouse cursor is located on item
        address = hitTestInfo.Item.Address

        If (hitTestInfo.ItemPart And BetterListViewHitPart.VCenter) = BetterListViewHitPart.VCenter Then

            ' the mouse cursor is located in the centre of the item - the insertion mark will point inside the item
            dropPart = BetterListViewDropPart.Inside

        Else

            ' the mouse cursor is located on other parts of the item - the insertion mark will point before on after the item
            dropPart = (If(((hitTestInfo.ItemPart And BetterListViewHitPart.Bottom) = BetterListViewHitPart.Bottom), BetterListViewDropPart.After, BetterListViewDropPart.Before))

        End If

    ElseIf hitTestInfo.Group IsNot Nothing Then

        ' the mouse cursor is located on group
        address = hitTestInfo.Group.Address
        'NOTE: only Inside is allowed as drop part on groups
        dropPart = BetterListViewDropPart.Inside

    Else

        ' the mouse cursor is not located on item nor group
        address = Nothing
        dropPart = BetterListViewDropPart.Undefined

    End If

    If address IsNot Nothing Then

        ' set insertion mark on the constructed location
        ListView.InsertionMark = New BetterListViewInsertionMark(New BetterListViewInsertionLocation(address, dropPart))

    Else

        ' reset insertion mark
        ListView.InsertionMark = BetterListViewInsertionMark.Empty

    End If

End Sub