private void OnSelectedItemsChanged(SelectionChangedEventArgs args) { //Logic - by default when items scroll out of view they are no longer selected. //this is because the panel is virtualised and and automatically unselected due //to the control thinking that the item is not longer part of the overall collection if (_isSelecting) return; try { _isSelecting = true; _selected.Edit(innerList => { var toAdd = args.AddedItems.OfType<LineProxy>().ToList(); //may need to track if last selected is off the page: var isShiftKeyDown = Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift); //get the last item at then end of the list if (!isShiftKeyDown) { //if mouse down, we need to prevent items being cleated //add items to list foreach (var lineProxy in toAdd) { if (innerList.Contains(lineProxy)) continue; _lastSelected = lineProxy; innerList.Add(lineProxy); } } else { if (_lastSelected == null) { foreach (var lineProxy in toAdd) { if (innerList.Contains(lineProxy)) continue; _lastSelected = lineProxy; innerList.Add(lineProxy); } args.Handled = true; return; } //if shift down we need to override selected and manually select our selves var last = _lastSelected.Index; var allSelectedItems = _selector.SelectedItems.OfType<LineProxy>().ToArray(); var currentPage = _selector.Items.OfType<LineProxy>().ToArray(); //1. Determine whether all selected items are on the current page [plus whether last is on the current page] var allOnCurrentPage = allSelectedItems.Intersect(currentPage).ToArray(); var lastInONcurrentPage = currentPage.Contains(_lastSelected); if (lastInONcurrentPage && allOnCurrentPage.Length == allSelectedItems.Length) { innerList.Clear(); innerList.AddRange(allSelectedItems); return; } args.Handled = true; var maxOfRecent = toAdd.Max(lp => lp.Index); int min; int max; if (last < maxOfRecent) { min = last; max = maxOfRecent; } else { min = maxOfRecent; max = last; } //maintain selection _selector.SelectedItems.Clear(); var fromCurrentPage = _selector.Items.OfType<LineProxy>() .Where(lp => lp.Index >= min && lp.Index <= max) .ToArray(); var fromPrevious = _recentlyRemovedFromVisibleRange .Items.Where(lp => lp.Index >= min && lp.Index <= max) .ToArray(); _recentlyRemovedFromVisibleRange.Clear(); //maintain our record innerList.Clear(); innerList.AddRange(fromCurrentPage); foreach (var previous in fromPrevious) { if (!innerList.Contains(previous)) innerList.Add(previous); } //finally reload the actual selection: foreach (var item in innerList) { _selector.SelectedItems.Add(item); } } }); } catch (Exception ex) { _logger.Error(ex,"There has been a problem with manual selection"); } finally { _isSelecting = false; } }
private void ClearAllSelections() { _selected.Clear(); _recentlyRemovedFromVisibleRange.Clear(); _lastSelected = null; }