// Measure horizontally. protected override Size MeasureOverride(Size constraint) { Size desiredSize = new Size(); DataGridContext dataGridContext = this.DataGridContext; // DataGridContext can be null when a the parent Row was not prepared if (dataGridContext == null) { return(this.DesiredSize); } TableViewColumnVirtualizationManager columnVirtualizationManager = dataGridContext.ColumnVirtualizationManager as TableViewColumnVirtualizationManager; foreach (Cell cell in this.GetVisibleCells()) { Debug.Assert(!Row.GetIsTemplateCell(cell), "No template Cells should be added to FixedCellPanel"); cell.Measure(new Size(columnVirtualizationManager.FieldNameToWidth[cell.FieldName], constraint.Height)); if (cell.DesiredSize.Height > desiredSize.Height) { desiredSize.Height = cell.DesiredSize.Height; } } desiredSize.Width = columnVirtualizationManager.FixedColumnsWidth; return(desiredSize); }
private static void OnColumnReordering(object sender, ColumnReorderingEventArgs e) { FixedCellPanel panel = sender as FixedCellPanel; if (panel == null) { return; } DataGridContext dataGridContext = DataGridControl.GetDataGridContext(panel); if (dataGridContext == null) { return; } TableViewColumnVirtualizationManager columnVirtualizationManager = dataGridContext.ColumnVirtualizationManager as TableViewColumnVirtualizationManager; if (columnVirtualizationManager == null) { return; } int currentFixedColumnCount = columnVirtualizationManager.FixedColumnCount; // We must be sure the VisiblePosition is converted to visible index since some Columns can be Visible = false int oldVisiblePosition = FixedCellPanel.CalculateVisibleIndex(e.OldVisiblePosition, dataGridContext); int newVisiblePosition = FixedCellPanel.CalculateVisibleIndex(e.NewVisiblePosition, dataGridContext); if ((oldVisiblePosition < columnVirtualizationManager.FixedColumnCount) && (newVisiblePosition >= columnVirtualizationManager.FixedColumnCount)) { // A column was moved from the fixedPanel to the scrollingPanel // Do not increment version, it will be done by the FixedColumnCount changed TableView.SetFixedColumnCount(columnVirtualizationManager.DataGridContext, columnVirtualizationManager.FixedColumnCount - 1); } else if ((oldVisiblePosition >= columnVirtualizationManager.FixedColumnCount) && (newVisiblePosition < columnVirtualizationManager.FixedColumnCount)) { // A column was moved from the scrollingPanel to the fixedPanel // Do not increment version, it will be done by the FixedColumnCount changed TableView.SetFixedColumnCount(columnVirtualizationManager.DataGridContext, columnVirtualizationManager.FixedColumnCount + 1); } else { columnVirtualizationManager.IncrementVersion(new UpdateMeasureRequiredEventArgs(UpdateMeasureTriggeredAction.ColumnReordering)); } // This must be done to stop progation of the event even // if only 1 ColumnManagerCell will raise it. e.Handled = true; }
private static void OnFirstColumnCompensationOffsetChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { TableViewColumnVirtualizationManager manager = sender as TableViewColumnVirtualizationManager; if (manager == null) { return; } manager.m_firstColumnCompensationOffset = ( double )e.NewValue; manager.IncrementVersion(new UpdateMeasureRequiredEventArgs(UpdateMeasureTriggeredAction.Unspecified)); }
protected override void StopListening(object source) { TableViewColumnVirtualizationManager columnVirtualizationManager = source as TableViewColumnVirtualizationManager; if (columnVirtualizationManager != null) { columnVirtualizationManager.UpdateMeasureRequired -= this.OnUpdateMeasureRequired; return; } throw new InvalidOperationException("An attempt was made to use a source other than a ColumnVirtualizationManager."); }
protected virtual IEnumerable <string> GetVisibleFieldsName() { DataGridContext dataGridContext = this.DataGridContext; if (dataGridContext == null) { return(new string[0]); } TableViewColumnVirtualizationManager columnVirtualizationManager = dataGridContext.ColumnVirtualizationManager as TableViewColumnVirtualizationManager; return(columnVirtualizationManager.FixedFieldNames); }
private static void OnIsVirtualizingChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) { TableViewColumnVirtualizationManager columnVirtualizationManager = o as TableViewColumnVirtualizationManager; if (columnVirtualizationManager == null) { return; } if (e.NewValue != null) { columnVirtualizationManager.m_flags[( int )TableViewColumnVirtualizationManagerFlags.IsVirtualizing] = ( bool )e.NewValue; columnVirtualizationManager.IncrementVersion(new UpdateMeasureRequiredEventArgs(UpdateMeasureTriggeredAction.VirtualizationStateChanged)); } }
private static void OnFixedColumnCountChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) { TableViewColumnVirtualizationManager columnVirtualizationManager = o as TableViewColumnVirtualizationManager; if (columnVirtualizationManager == null) { return; } if (e.NewValue != null) { columnVirtualizationManager.m_fixedColumnCount = ( int )e.NewValue; // We want to be sure the cells won't be inserted in ScrollingPanel, but added to it columnVirtualizationManager.IncrementVersion(new UpdateMeasureRequiredEventArgs(UpdateMeasureTriggeredAction.ColumnReordering)); } }
// Arrange horizontally. protected override Size ArrangeOverride(Size arrangeSize) { DataGridContext dataGridContext = this.DataGridContext; // DataGridContext can be null when the parent Row was not prepared if (dataGridContext == null) { return(this.DesiredSize); } TableViewColumnVirtualizationManager columnVirtualizationManager = dataGridContext.ColumnVirtualizationManager as TableViewColumnVirtualizationManager; Dictionary <string, double> columnToVisibleOffset = columnVirtualizationManager.FieldNameToOffset; ScrollViewer parentScrollViewer = dataGridContext.DataGridControl.ScrollViewer; double horizontalOffset = parentScrollViewer.HorizontalOffset; double fixedColumnVisibleWidth = columnVirtualizationManager.FixedColumnsWidth; double firstColumnCompensationOffset = columnVirtualizationManager.FirstColumnCompensationOffset; Rect finalRect = new Rect(arrangeSize); foreach (Cell cell in this.GetCellsToLayout()) { // Calculate the offset of the Cell: // The original offset of the Column // - the horizontal offset of the ScrollViewer to scroll to the right // - the width of the fixed columns since we are in the Scrolling FixedCellSubPanel // + the compensation offset used in master detail to avoid scrolling when not required double cellOffset = columnToVisibleOffset[cell.FieldName] - horizontalOffset - fixedColumnVisibleWidth + firstColumnCompensationOffset; finalRect.X = cellOffset; finalRect.Width = cell.DesiredSize.Width; finalRect.Height = Math.Max(arrangeSize.Height, cell.DesiredSize.Height); cell.Arrange(finalRect); } return(arrangeSize); }
// Measure horizontally. protected override Size MeasureOverride(Size constraint) { Size desiredSize = new Size(); DataGridContext dataGridContext = this.DataGridContext; // DataGridContext can be null when a the parent Row was not prepared if (dataGridContext == null) { return(this.DesiredSize); } TableViewColumnVirtualizationManager columnVirtualizationManager = dataGridContext.ColumnVirtualizationManager as TableViewColumnVirtualizationManager; Dictionary <string, double> columnToVisibleWidth = columnVirtualizationManager.FieldNameToWidth; foreach (Cell cell in this.GetCellsToLayout()) { double width; if (columnToVisibleWidth.TryGetValue(cell.FieldName, out width)) { cell.Measure(new Size(width, constraint.Height)); } else { // The cell will be hidden. cell.Measure(Size.Empty); } if (cell.DesiredSize.Height > desiredSize.Height) { desiredSize.Height = cell.DesiredSize.Height; } } desiredSize.Width = columnVirtualizationManager.ScrollingColumnsWidth; return(desiredSize); }
internal void UpdateReorderingInfo( TableViewColumnVirtualizationManager columnVirtualizationManager ) { // Do not create another instance since we want to keep the NewFixedColumnCount RequiredAnimationsInfo animationState = this.RequiredAnimations; animationState.AnimateToLeft.Clear(); animationState.AnimateToRight.Clear(); animationState.RollbackAnimation.Clear(); List<ColumnBase> columnsByVisiblePosition = this.InitialColumnsByVisiblePosition; List<ColumnBase> reorderedColumnsByVisiblePosition = this.ReorderedColumnsByVisiblePosition; Debug.Assert( this.InitialColumnVisiblePosition < this.InitialColumnsByVisiblePosition.Count ); ColumnBase draggedColumn = this.InitialColumnsByVisiblePosition[ this.InitialColumnVisiblePosition ]; bool draggedColumnReached = false; int visibleColumnCount = columnsByVisiblePosition.Count; Dictionary<string, object> columnsInView = columnVirtualizationManager.FixedAndScrollingFieldNamesLookupDictionary; for( int i = 0; i < visibleColumnCount; i++ ) { ColumnBase originalColumn = columnsByVisiblePosition[ i ]; ColumnBase reorderedColumn = reorderedColumnsByVisiblePosition[ i ]; if( reorderedColumn == draggedColumn ) { draggedColumnReached = true; continue; } if( !reorderedColumn.Visible ) continue; if( originalColumn == reorderedColumn ) { animationState.RollbackAnimation.Add( reorderedColumn ); continue; } if( columnsInView.ContainsKey( reorderedColumn.FieldName ) ) { if( !draggedColumnReached ) { animationState.AnimateToLeft.Add( reorderedColumn ); } else { animationState.AnimateToRight.Add( reorderedColumn ); } } } animationState.DraggedColumnNewVisiblePosition = reorderedColumnsByVisiblePosition.IndexOf( draggedColumn ); }
private void AdjustCellTabIndex( TableViewColumnVirtualizationManager columnVirtualizationManager ) { // The order of the children in the panel is not guaranteed to be good. We do not // reorder children because we will have to remove and add them at a different location. // Doing that will cause more calculations to occur, so we only change the TabIndex. VirtualizingCellCollection collection = this.ParentRowCells; if( collection == null ) return; HashSet<string> bindedFields = new HashSet<string>(); foreach( Cell cell in collection.BindedCells ) { bindedFields.Add( cell.FieldName ); this.AdjustCellTabIndex( columnVirtualizationManager, cell ); } List<string> targetFields = new List<string>(); targetFields.AddRange( columnVirtualizationManager.FixedFieldNames ); targetFields.AddRange( columnVirtualizationManager.ScrollingFieldNames ); targetFields.AddRange( m_permanentScrollingFieldNames ); foreach( string fieldName in targetFields ) { if( bindedFields.Contains( fieldName ) ) continue; Cell cell = collection[ fieldName ]; Debug.Assert( cell != null ); this.AdjustCellTabIndex( columnVirtualizationManager, cell ); } }
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; }
private void AdjustCellTabIndex( TableViewColumnVirtualizationManager columnVirtualizationManager, Cell targetCell ) { int tabIndex; if( columnVirtualizationManager.FieldNameToPosition.TryGetValue( targetCell.FieldName, out tabIndex ) ) { if( tabIndex != KeyboardNavigation.GetTabIndex( targetCell ) ) { KeyboardNavigation.SetTabIndex( targetCell, tabIndex ); } } else { targetCell.ClearValue( Cell.TabIndexProperty ); } }