public override void MouseDown( MouseEventArgs e ) { RowSection rowSectionSelected = GetRowSectionFromPoint( new Point( e.X, e.Y ) ); if( rowSectionSelected == null ) { return; } RowIdentifier ri = rowSectionSelected.RowIdentifier; PositionedRowIdentifier si = new PositionedRowIdentifier( ri, rowSectionSelected.Position ); if( !SelectedItems.Contains( ri ) ) { SetFocusWithSelectionCheck( si ); _mouseClickHandled = true; } else { _mouseClickHandled = false; FocusedItem = si; } }
public override void KeyDown( KeyEventArgs e ) { if( RowInformation == null ) { return; } bool shiftBeingPressed = (e.Modifiers & Keys.Shift) == Keys.Shift; bool ctrlBeingPressed = (e.Modifiers & Keys.Control) == Keys.Control; int? newPos = null; switch( e.KeyCode ) { case Keys.Subtract: case Keys.Left: { if( FocusedItem != null ) { PositionedRowIdentifier groupItem; int position = FocusedItem.Position; if( FocusedItem.RowIdentifier.GroupColumns != null ) { GroupIdentifier gi = FocusedItem.RowIdentifier as GroupIdentifier; if (gi != null) { if (GetGroupState(gi) == GroupState.Collapsed && position > 0) { --position; } } } groupItem = FindGroupFromRowIdentifier( position ); if( groupItem != null ) { SetFocusWithSelectionCheck( groupItem ); SetGroupState( groupItem.RowIdentifier, GroupState.Collapsed, true ); } } } break; case Keys.Add: case Keys.Right: { if( FocusedItem != null ) { PositionedRowIdentifier groupItem = FindGroupFromRowIdentifier( FocusedItem.Position ); if( groupItem != null ) { SetGroupState( groupItem.RowIdentifier, GroupState.Expanded, false ); } } } break; case Keys.Multiply: SetGlobalGroupState( GroupState.Expanded ); break; case Keys.Divide: SetGlobalGroupState( GroupState.Collapsed ); break; case Keys.Down: newPos = _focusedItem == null ? 0 : _focusedItem.Position + 1; break; case Keys.Up: if( _focusedItem != null ) { newPos = _focusedItem.Position - 1; } break; case Keys.Space: if( FocusedItem != null ) { if( shiftBeingPressed ) { SelectedItems.AddInternal( FocusedItem.RowIdentifier ); } else { SelectedItems.ClearAndAdd( FocusedItem.RowIdentifier ); } return; } break; case Keys.PageDown: newPos = _focusedItem == null ? _countDisplayed : _focusedItem.Position + _countDisplayed; break; case Keys.PageUp: if( _focusedItem != null ) { newPos = _focusedItem.Position - _countDisplayed; } break; case Keys.End: newPos = RowInformation.Count; break; case Keys.Home: newPos = 0; break; } if( newPos == null ) { return; // nothing to do } // // Bounds check if( newPos.Value >= RowInformation.Count ) { newPos = RowInformation.Count - 1; } if( newPos.Value < 0 ) { newPos = 0; } if( newPos.Value < RowInformation.Count ) { RowIdentifier ri = RowInformation[newPos.Value]; PositionedRowIdentifier newFocusedItem = new PositionedRowIdentifier( ri, newPos.Value ); if( ctrlBeingPressed ) { FocusedItem = newFocusedItem; } else { SetFocusWithSelectionCheck( newFocusedItem ); } } }
public override void MouseClick( MouseEventArgs e ) { base.MouseClick( e ); if( !_mouseClickHandled && e.Button != MouseButtons.Right ) { _mouseClickHandled = true; RowSection rowSectionSelected = GetRowSectionFromPoint( new Point( e.X, e.Y ) ); if( rowSectionSelected == null ) { return; } RowIdentifier ri = rowSectionSelected.RowIdentifier; PositionedRowIdentifier si = new PositionedRowIdentifier( ri, rowSectionSelected.Position ); SetFocusWithSelectionCheck( si ); } }
private void SetFocusWithSelectionCheck( PositionedRowIdentifier si ) { FocusedItem = si; bool shiftBeingPressed = (Control.ModifierKeys & Keys.Shift) == Keys.Shift; bool ctrlBeingPressed = (Control.ModifierKeys & Keys.Control) == Keys.Control; if( AllowMultiSelect && _lastRowSelected != null && shiftBeingPressed ) { RowIdentifier anchor = _lastRowSelected.RowIdentifier; int from; int to; if( _lastRowSelected.Position < si.Position ) { from = _lastRowSelected.Position; to = si.Position; } else { to = _lastRowSelected.Position; from = si.Position; } List<RowIdentifier> selectedItems = new List<RowIdentifier>(); foreach( RowIdentifier rowInfo in GetRowEnumerator( from, Direction.Forward ) ) { selectedItems.Add( rowInfo ); if( from++ == to ) { break; } } if( ctrlBeingPressed ) { SelectedItems.AddRangeInternal( selectedItems.ToArray() ); } else { SelectedItems.ClearAndAdd( selectedItems.ToArray() ); } } else { if( ctrlBeingPressed ) { if( SelectedItems.IsSelected( si.RowIdentifier ) ) { SelectedItems.RemoveInternal( si.RowIdentifier ); } else { if( AllowMultiSelect ) { // if MultiSelect is set to true, add the newly clicked item to the selected items collection SelectedItems.AddInternal( si.RowIdentifier ); } else { // if MutliSelect is set to false, clear the selected items collection and add the newly clicked item. SelectedItems.ClearAndAdd( si.RowIdentifier ); } } } else { if( !SelectedItems.IsSelected( si.RowIdentifier ) || SelectedItems.Count != 1 ) { SelectedItems.Clear(); SelectedItems.AddInternal( si.RowIdentifier ); } } _lastRowSelected = si; } }
private bool IsSelectedItemValid( PositionedRowIdentifier item ) { return item != null && (item.Position < _rowInformation.Count && _rowInformation[item.Position] == item.RowIdentifier); }
private void HandleSyncing( RowIdentifier ri, int newPosition, PositionedRowIdentifier[] trackableItems, List<PositionedRowIdentifier> newSelection ) { foreach( PositionedRowIdentifier si in trackableItems ) { if( si != null ) { if( ri.Equals( si.RowIdentifier ) ) { si.Position = newPosition; } } } if( SelectedItems.Contains( ri ) ) { newSelection.Add( new PositionedRowIdentifier( ri, newPosition ) ); } }
/// <summary> /// Returns the number of items in the list adjusted for the group items. /// This method will also create a bit array of types <seealso cref="_positionTypes"/> /// </summary> /// <returns></returns> private int CalculateListItems() { using( new EnforceLazyLayout( this ) ) { if( _rowInformation == null ) { PositionedRowIdentifier[] trackableItems = new PositionedRowIdentifier[3]; trackableItems[0] = _focusedItem; if( _lastCalculatedRowInformation != null ) { if( FocusedItem != null ) { if( LineStart < _lastCalculatedRowInformation.Count ) { trackableItems[1] = new PositionedRowIdentifier( _lastCalculatedRowInformation[LineStart], LineStart ); } RowIdentifier nextValidRow = locateNearestRowThatsStillValid( FocusedItem, ItemList, _lastCalculatedRowInformation ); if( nextValidRow != null ) { trackableItems[2] = new PositionedRowIdentifier( nextValidRow, 0 ); } } } Column[] groupColumns = ListControl.Columns.GroupedItems.ToArray(); object lastItem = null; _lastCalculatedRowInformation = _rowInformation = new List<RowIdentifier>( ItemList.Count ); int hideRowGroupIndex = -1; List<PositionedRowIdentifier> newSelection = new List<PositionedRowIdentifier>(); GroupIdentifier[] activeGroups = new GroupIdentifier[groupColumns.Length]; object[] listItems = ItemList.ToArray(); for( int i = 0; i < ItemList.Count; i++ ) { object item = ItemList[i]; int groupIndex = ItemInNewGroup( groupColumns, item, lastItem ); if( groupIndex != -1 ) { for( int iGroup = groupIndex; iGroup < groupColumns.Length; iGroup++ ) { GroupIdentifier gi = new GroupIdentifier( i, listItems, Columns, iGroup, item ); int hideGroupIndex = hideRowGroupIndex; if( hideRowGroupIndex == -1 || iGroup <= hideRowGroupIndex ) { if( GetGroupState( gi ) == GroupState.Collapsed ) { hideGroupIndex = iGroup; if( groupIndex <= hideRowGroupIndex ) { hideRowGroupIndex = -1; } } else { hideRowGroupIndex = hideGroupIndex = -1; } } if( hideRowGroupIndex == -1 ) { HandleSyncing( gi, _rowInformation.Count, trackableItems, newSelection ); _rowInformation.Add( gi ); } if( activeGroups[iGroup] != null ) { activeGroups[iGroup].End = i; } activeGroups[iGroup] = gi; hideRowGroupIndex = hideGroupIndex; } } if( hideRowGroupIndex == -1 ) { RowIdentifier ri = new NonGroupRow( item ); HandleSyncing( ri, _rowInformation.Count, trackableItems, newSelection ); _rowInformation.Add( ri ); } lastItem = item; } foreach( GroupIdentifier gi in activeGroups ) { if( gi != null ) { gi.End = ItemList.Count; } } if( VerticalScrollbarVisible ) { int newMax = _rowInformation.Count == 0 ? 0 : _rowInformation.Count - 1; if( VScrollbar.Value >= newMax ) { VScrollbar.Value = newMax; } VScrollbar.Maximum = newMax; } if( trackableItems[1] != null ) { LineStart = trackableItems[1].Position; } if( _focusedItem != null && !IsSelectedItemValid( _focusedItem ) ) { if( trackableItems[2] != null && IsSelectedItemValid( trackableItems[2] ) ) { PositionedRowIdentifier oldFocusedItem = _focusedItem; if( _focusedItem != trackableItems[2] ) { _focusedItem = trackableItems[2]; ListControl.FireFocusChanged( oldFocusedItem == null ? null : oldFocusedItem.RowIdentifier, _focusedItem == null ? null : _focusedItem.RowIdentifier ); } newSelection.Add( _focusedItem ); } else { int newPosition; if( _focusedItem.Position >= _rowInformation.Count ) { newPosition = _rowInformation.Count - 1; } else { newPosition = _focusedItem.Position; } if( newPosition >= 0 ) { PositionedRowIdentifier si = new PositionedRowIdentifier( _rowInformation[newPosition], newPosition ); FocusedItem = si; newSelection.Add( _focusedItem ); } else { FocusedItem = null; } } } RowIdentifier[] rowItemsToSelect = new RowIdentifier[newSelection.Count]; int j = 0; foreach( PositionedRowIdentifier pri in newSelection ) { rowItemsToSelect[j++] = pri.RowIdentifier; } SelectedItems.ClearAndAdd( rowItemsToSelect ); if( SelectedItems.Count == 0 && FocusedItem == null && VScrollbar != null && VScrollbar.Visible ) { VScrollbar.Value = 0; } } _mapOfPositions = null; } ListControl.OnCalculatedGroupRows( EventArgs.Empty ); return _rowInformation.Count; }
private static RowIdentifier locateNearestRowThatsStillValid( PositionedRowIdentifier current, ItemLists.ItemList itemList, List<RowIdentifier> oldList ) { // // Check forward first for( int i = current.Position; i < oldList.Count; i++ ) { RowIdentifier ri = oldList[i]; if( IsValidNextRow( current.RowIdentifier, ri, itemList ) ) { return ri; } } // // Check backwards now for( int i = current.Position - 1; i >= 0 && i < oldList.Count; i-- ) { RowIdentifier ri = oldList[i]; if( IsValidNextRow( current.RowIdentifier, ri, itemList ) ) { return ri; } } return null; }