protected IEnumerable <Cell> GetVisibleCells() { VirtualizingCellCollection collection = this.ParentPanel.ParentRowCells; if (collection == null) { yield break; } foreach (string fieldName in this.GetVisibleFieldsName()) { yield return(collection.GetCell(fieldName, false)); } }
private IEnumerable <Cell> GetCellsToLayout(IEnumerable <Cell> visibleCells, IEnumerable <string> permanentScrollingFieldNames, VirtualizingCellCollection cellsCollection) { List <string> unhandledCells = permanentScrollingFieldNames.ToList(); foreach (var cell in visibleCells) { unhandledCells.Remove(cell.FieldName); yield return(cell); } foreach (var fieldName in unhandledCells) { var cell = cellsCollection.GetCell(fieldName, false); Debug.Assert(cell != null); yield return(cell); } }
private IEnumerable<Cell> GetCellsToLayout( IEnumerable<Cell> visibleCells, IEnumerable<string> permanentScrollingFieldNames, VirtualizingCellCollection cellsCollection ) { List<string> unhandledCells = permanentScrollingFieldNames.ToList(); foreach( var cell in visibleCells ) { unhandledCells.Remove( cell.FieldName ); yield return cell; } foreach( var fieldName in unhandledCells ) { var cell = cellsCollection.GetCell( fieldName, false ); Debug.Assert( cell != null ); yield return cell; } }
protected Row() { this.CommandBindings.Add( new CommandBinding( DataGridCommands.BeginEdit, new ExecutedRoutedEventHandler( OnBeginEditExecuted ), new CanExecuteRoutedEventHandler( OnBeginEditCanExecute ) ) ); this.CommandBindings.Add( new CommandBinding( DataGridCommands.EndEdit, new ExecutedRoutedEventHandler( OnEndEditExecuted ), new CanExecuteRoutedEventHandler( OnEndEditCanExecute ) ) ); this.CommandBindings.Add( new CommandBinding( DataGridCommands.CancelEdit, new ExecutedRoutedEventHandler( OnCancelEditExecuted ), new CanExecuteRoutedEventHandler( OnCancelEditCanExecute ) ) ); // Cache the CellsCollection and always return it in the // getter of the DependencyProperty's CLR accessor m_cellsCache = new VirtualizingCellCollection( this ); // Set the Value of the DependencyProperty this.SetValue( Row.CellsPropertyKey, m_cellsCache ); }
internal static void RemoveListener( VirtualizingCellCollection source, IWeakEventListener listener ) { VirtualizingCellCollectionChangedEventManager.CurrentManager.ProtectedRemoveListener( source, listener ); }
private void UpdateChildren( DataGridContext dataGridContext, TableViewColumnVirtualizationManagerBase columnVirtualizationManager, VirtualizingCellCollection parentRowCells ) { //Prevent reentrance if( ( parentRowCells == null ) || m_parentRowCells.IsUpdating ) return; using( m_parentRowCells.SetIsUpdating() ) { this.ClearPermanentScrollingFieldNames(); //Retrieve the cells that aren't needed anymore. var unusedCells = ( from cell in parentRowCells.BindedCells where !columnVirtualizationManager.GetScrollingFieldNames( m_parentRow.LevelCache ).Contains( cell.FieldName ) && !columnVirtualizationManager.GetFixedFieldNames( m_parentRow.LevelCache ).Contains( cell.FieldName ) select cell ).ToList(); //Release the unused binded cells now in order to minimize the number of cell's creation. foreach( Cell cell in unusedCells ) { this.AddCellToVisualTree( cell ); if( this.CanReleaseCell( cell ) ) { // Ensure to close the ContextMenu if it is open and the Cell is virtualized to avoid problems with ContextMenus defined as static resources // that won't be able to reopen again if the Close private method is called after the PlacementTarget is removed from the VisualTree var contextMenu = cell.ContextMenu; if( ( contextMenu != null ) && ( contextMenu.IsOpen ) ) { contextMenu.IsOpen = false; } cell.ClearContainer(); parentRowCells.Release( cell ); } //Since the cell cannot be released, it will not be collapsed. We must keep the field //name in order to let the scrolling sub-panel measure and arrange the cell out of view. else { //Certain non recyclable cells like StatCells needs their content binding to be removed when they become out of view. cell.RemoveContentBinding(); this.AddPermanentScrollingFieldNames( cell.FieldName ); } } //Add the missing cells to the fixed region. foreach( string fieldName in columnVirtualizationManager.GetFixedFieldNames( m_parentRow.LevelCache ) ) { //The cell is created if it is missing. Cell cell = parentRowCells[ fieldName ]; //Certain non recyclable cells like StatCells need their content binding to be updated when they become (or stay) in view. cell.AddContentBinding( dataGridContext, this.ParentRow, this.Columns[ cell.FieldName ] ); //Make sure the cell is in the appropriate panel. this.MoveCellToFixedPanel( cell ); } //Add the missing cells to the scrolling region. foreach( string fieldName in columnVirtualizationManager.GetScrollingFieldNames( m_parentRow.LevelCache ) ) { //The cell is created if it is missing. Cell cell = parentRowCells[ fieldName ]; //Certain non recyclable cells like StatCells need their content binding to be updated when they become (or stay) in view. cell.AddContentBinding( dataGridContext, this.ParentRow, this.Columns[ cell.FieldName ] ); //Make sure the cell is in the appropriate panel. this.MoveCellToScrollingPanel( cell ); } if( m_clearUnusedCellsDispatcherOperation == null ) { m_clearUnusedCellsDispatcherOperation = this.Dispatcher.BeginInvoke( new Action( this.ClearUnusedCells ), DispatcherPriority.ApplicationIdle ); } m_fixedPanel.InvalidateMeasure(); m_scrollingCellsDecorator.InvalidateMeasure(); m_scrollingPanel.InvalidateMeasure(); } }
private void UpdateChildren( DataGridContext dataGridContext, TableViewColumnVirtualizationManager columnVirtualizationManager, VirtualizingCellCollection parentRowCells ) { //Prevent reentrance if( m_parentRowCells.AlreadyUpdating ) return; m_parentRowCells.AlreadyUpdating = true; if( dataGridContext == null ) throw new DataGridInternalException( "DataGridContext is null for FixedCellPanel" ); if( columnVirtualizationManager == null ) throw new DataGridInternalException( "ColumnVirtualizationManager is null for FixedCellPanel" ); if( parentRowCells == null ) return; this.ClearPermanentScrollingFieldNames(); List<string> currentFieldsName = new List<string>(); currentFieldsName.AddRange( columnVirtualizationManager.FixedFieldNames ); currentFieldsName.AddRange( columnVirtualizationManager.ScrollingFieldNames ); HashSet<Cell> unusedCells = new HashSet<Cell>( parentRowCells.BindedCells ); //Idenfity the binded cells that aren't needed anymore. foreach( string fieldName in currentFieldsName ) { ColumnBase column = dataGridContext.Columns[ fieldName ]; Cell cell; if( parentRowCells.TryGetCell( column, out cell ) ) { //Certain non recyclable cells like StatCells need their content binding to be updated when they become (or stay) in view. cell.AddContentBinding(); unusedCells.Remove( cell ); } } currentFieldsName.Clear(); currentFieldsName.TrimExcess(); //Release the unused binded cells now in order to minimize the number of cell's creation. foreach( Cell cell in unusedCells ) { bool release = this.CanReleaseCell( cell ); //We move the unused cell into the scrolling panel since there is more chance it will be reused there in the future. this.MoveCellToScrollingPanel( cell, release ); if( release ) { parentRowCells.Release( cell ); } //Since the cell cannot be released, it will not be collapsed. We must keep the field name in order to let the scrolling sub-panel measure and arrange the cell out of view. else { //Certain non recyclable cells like StatCells needs their content binding to be removed when they become out of view. cell.RemoveContentBinding(); this.AddPermanentScrollingFieldNames( cell.FieldName ); } } unusedCells.Clear(); unusedCells.TrimExcess(); //Add the missing cells to the fixed region. foreach( string fieldName in columnVirtualizationManager.FixedFieldNames ) { //The cell is created if it is missing. Cell cell = parentRowCells[ fieldName ]; //Make sure the cell is in the appropriate panel. this.MoveCellToFixedPanel( cell ); } //Add the missing cells to the scrolling region. foreach( string fieldName in columnVirtualizationManager.ScrollingFieldNames ) { //The cell is created if it is missing. Cell cell = parentRowCells[ fieldName ]; //Make sure the cell is in the appropriate panel. this.MoveCellToScrollingPanel( cell ); } if( m_clearUnusedCellsDispatcherOperation == null ) { m_clearUnusedCellsDispatcherOperation = this.Dispatcher.BeginInvoke( new Action( this.ClearUnusedCells ), DispatcherPriority.ApplicationIdle ); } m_fixedPanel.InvalidateMeasure(); m_scrollingCellsDecorator.InvalidateMeasure(); m_scrollingPanel.InvalidateMeasure(); m_parentRowCells.AlreadyUpdating = false; }