Issues (and a fix) for Items selection for the ListBox

Mar 5, 2013 at 8:30 PM
The current implementation disables selection on listboxes, it took me a while to figure out how to do it, but here is my fix:

First, Make OnManipulationStarted, OnManipulationCompleted on the TouchScrollBehaviorBase virtual...

Replace the ListBoxTouchScrollBehavior with the following:-
/// <summary>
/// Implementation of the Touch Scroll Behavior for <see cref="ListBox"/> controls
/// </summary>
public class ListBoxTouchScrollBehavior : TouchScrollBehaviorBase<ListBox>
{

    // Tolerance X
    public double SelectToleranceX
    {
        get { return (double)GetValue(SelectToleranceXProperty); }
        set { SetValue(SelectToleranceXProperty, value); }
    }

    // Using a DependencyProperty as the backing store for SelectToleranceX.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty SelectToleranceXProperty =
        DependencyProperty.Register("SelectToleranceX", typeof(double), typeof(ListBoxTouchScrollBehavior), new PropertyMetadata(40.0));

    // Tolerance Y
    public double SelectToleranceY
    {
        get { return (double)GetValue(SelectToleranceYProperty); }
        set { SetValue(SelectToleranceYProperty, value); }
    }

    // Using a DependencyProperty as the backing store for SelectToleranceX.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty SelectToleranceYProperty =
        DependencyProperty.Register("SelectToleranceY", typeof(double), typeof(ListBoxTouchScrollBehavior), new PropertyMetadata(40.0));


    private ScrollViewer _associatedScrollViewer;

    /// <summary>
    /// Gets the associated scroll viewer.
    /// </summary>
    /// <value>The associated scroll viewer.</value>
    protected override ScrollViewer AssociatedScrollViewer
    {
        get { return _associatedScrollViewer ?? (_associatedScrollViewer = AssociatedObject.GetChild<ScrollViewer>()); }
    }

    ListBoxItem _ItemSaved = null;

    protected override void OnManipulationStarted(object sender, System.Windows.Input.Manipulations.Manipulation2DStartedEventArgs e)
    {
        Point p = new Point(e.OriginX, e.OriginY);

        foreach (UIElement element in VisualTreeHelper.FindElementsInHostCoordinates(p, this.AssociatedObject))
        {
            if (element is ListBoxItem)
            {
                _ItemSaved = element as ListBoxItem;
                break;
            }
        }

        base.OnManipulationStarted(sender, e);
    }


    protected override void OnManipulationCompleted(object sender, System.Windows.Input.Manipulations.Manipulation2DCompletedEventArgs e)
    {
        base.OnManipulationCompleted(sender, e);

        if (e.Total.TranslationX < this.SelectToleranceX && e.Total.TranslationY < this.SelectToleranceY)
        {
            if (_ItemSaved != null)
            {
                _ItemSaved.IsSelected = true;
            }
        }

        _ItemSaved = null;
    }
}