Hit Test

Hit test allows you to detect elements and element parts for a specified position in the control. There are two overrides of the HitTest method:

The returned structure BetterListViewHitTestInfo contains references to Better ListView elements (column, group, item, sub-item), element parts and even its state information.

Current hit test information changes every time user moves mouse from one element part to another (or to another element), or when state of the hovered element changes (e.g. column is pressed). Better ListView raises BetterListViewHitTestChanged event whenever this occurs.

BetterListViewHitTestInfo.Locations Property

Furthermore, this structure contains a Locations property, which is enumeration with flags of all the cursor locations. Of course, there is always just a single cursor position, but it can correspond to multiple locations. For example, when the mouse cursor is hovers over an item text, the Locations property has the following value:

C#

BetterListViewHitTestLocations.ContentArea | BetterListViewHitTestLocations.Item | BetterListViewHitTestLocations.ItemSelection | BetterListViewHitTestLocations.ItemText

Visual Basic

BetterListViewHitTestLocations.ContentArea Or BetterListViewHitTestLocations.Item Or BetterListViewHitTestLocations.ItemSelection Or BetterListViewHitTestLocations.ItemText

When the mouse cursor is inside the control, the Locations property has always the ContentArea flag on. The same rule applies within Better ListView elements.

To check for some specific location (e.g. expand button of a group), write the following expression in an if statement:

C#

(hitTestInfo.Locations & BetterListViewHitTestLocations.GroupExpandButton) == BetterListViewHitTestLocations.GroupExpandButton

Visual Basic

(hitTestInfo.Locations And BetterListViewHitTestLocations.GroupExpandButton) = BetterListViewHitTestLocations.GroupExpandButton

Difference between ItemDisplay and ItemSelection

There are two items returned by hit test, which are not necessarily the same: BetterListViewHitTestInfo.ItemDisplay and BetterListViewHitTestInfo.ItemSelection.

These two items differ when combined items are turned on (see Combined Items for more information).

The ItemDisplay property always refers to the displayed item under cursor regardless of combined items. The ItemSelection property refers to corresponding selectable item.

Sample Source Code

The following sample shows handler of BetterListViewHitTestChanged event setting comprehensive information about hit test in a TextBox:

C#

private void ListViewHitTestChanged(object sender, BetterListViewHitTestChangedEventArgs eventArgs)
{
    BetterListViewHitTestInfo hitTestInfo = eventArgs.HitTestInfoNew;
    StringBuilder sbHitTest = new StringBuilder();

    sbHitTest.AppendLine(String.Format("Locations: {0}", hitTestInfo.Locations));

    if ((hitTestInfo.Locations & BetterListViewHitTestLocations.ColumnHeader) == BetterListViewHitTestLocations.ColumnHeader)
    {
        sbHitTest.AppendLine();
        sbHitTest.AppendLine(String.Format("Column header: '{0}'", hitTestInfo.ColumnHeader.Text));
        sbHitTest.AppendLine(String.Format("Column header part: {0}", hitTestInfo.ColumnHeaderPart));
        sbHitTest.AppendLine(String.Format("Column header state: {0}", hitTestInfo.ColumnHeaderStateInfo.ColumnHeaderState));
    }

    if ((hitTestInfo.Locations & BetterListViewHitTestLocations.Group) == BetterListViewHitTestLocations.Group)
    {
        sbHitTest.AppendLine();
        sbHitTest.AppendLine(String.Format("Group: '{0}'", hitTestInfo.Group.Header));
        sbHitTest.AppendLine(String.Format("Group part: {0}", hitTestInfo.GroupPart));
        sbHitTest.AppendLine(String.Format("Group state: {0}", hitTestInfo.GroupStateInfo.GroupState));
        sbHitTest.AppendLine(String.Format("Group expand button state: {0}", hitTestInfo.GroupStateInfo.ExpandButtonState));
    }

    if ((hitTestInfo.Locations & BetterListViewHitTestLocations.Item) == BetterListViewHitTestLocations.Item)
    {
        sbHitTest.AppendLine();
        sbHitTest.AppendLine(String.Format("Item: '{0}'", hitTestInfo.ItemDisplay.Text));
        sbHitTest.AppendLine(String.Format("Item part: {0}", hitTestInfo.ItemPartDisplay));
        sbHitTest.AppendLine(String.Format("Item state: {0}", hitTestInfo.ItemStateInfo.ItemState));
    }

    if ((hitTestInfo.Locations & BetterListViewHitTestLocations.SubItem) == BetterListViewHitTestLocations.SubItem)
    {
        sbHitTest.AppendLine();
        sbHitTest.AppendLine(String.Format("Sub-item: '{0}'", hitTestInfo.SubItem.Text));
        sbHitTest.AppendLine(String.Format("Sub-item part: {0}", hitTestInfo.SubItemPart));
    }

    this.textBoxHitTest.Text = sbHitTest.ToString();
}

Visual Basic

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

    Dim hitTestInfo As BetterListViewHitTestInfo = eventArgs.HitTestInfoNew
    Dim sbHitTest As New StringBuilder()

    sbHitTest.AppendLine ([String].Format ("Locations: {0}", hitTestInfo.Locations))

    If _
        (hitTestInfo.Locations And BetterListViewHitTestLocations.ColumnHeader) =
        BetterListViewHitTestLocations.ColumnHeader Then

        sbHitTest.AppendLine()
        sbHitTest.AppendLine ([String].Format ("Column header: '{0}'", hitTestInfo.ColumnHeader.Text))
        sbHitTest.AppendLine ([String].Format ("Column header part: {0}", hitTestInfo.ColumnHeaderPart))
        sbHitTest.AppendLine ([String].Format ("Column header state: {0}",
                                               hitTestInfo.ColumnHeaderStateInfo.ColumnHeaderState))

    End If

    If (hitTestInfo.Locations And BetterListViewHitTestLocations.Group) = BetterListViewHitTestLocations.Group Then

        sbHitTest.AppendLine()
        sbHitTest.AppendLine ([String].Format ("Group: '{0}'", hitTestInfo.Group.Header))
        sbHitTest.AppendLine ([String].Format ("Group part: {0}", hitTestInfo.GroupPart))
        sbHitTest.AppendLine ([String].Format ("Group state: {0}", hitTestInfo.GroupStateInfo.GroupState))
        sbHitTest.AppendLine ([String].Format ("Group expand button state: {0}",
                                               hitTestInfo.GroupStateInfo.ExpandButtonState))

    End If

    If (hitTestInfo.Locations And BetterListViewHitTestLocations.Item) = BetterListViewHitTestLocations.Item Then

        sbHitTest.AppendLine()
        sbHitTest.AppendLine ([String].Format ("Item: '{0}'", hitTestInfo.ItemDisplay.Text))
        sbHitTest.AppendLine ([String].Format ("Item part: {0}", hitTestInfo.ItemPartDisplay))
        sbHitTest.AppendLine ([String].Format ("Item state: {0}", hitTestInfo.ItemStateInfo.ItemState))

    End If

    If (hitTestInfo.Locations And BetterListViewHitTestLocations.SubItem) = BetterListViewHitTestLocations.SubItem _
        Then

        sbHitTest.AppendLine()
        sbHitTest.AppendLine ([String].Format ("Sub-item: '{0}'", hitTestInfo.SubItem.Text))
        sbHitTest.AppendLine ([String].Format ("Sub-item part: {0}", hitTestInfo.SubItemPart))

    End If

    TextBoxHitTest.Text = sbHitTest.ToString()

End Sub