private void MoveGhostToMousePosition( Point mousePosition ) { // Ensure the opacity of the ghost is correctly set this.ShowDraggedColumnGhosts(); Point currentAdornerPosition = mousePosition; if( m_elementToDraggedElementAdorner.Count == 0 ) return; int remainingDuration = this.ReturnToOriginalPositionDuration; if( m_ghostToMousePositionAnimationClock != null ) { PointAnimation pointAnimation = m_ghostToMousePositionAnimationClock.Timeline as PointAnimation; Point currentValue = pointAnimation.To.GetValueOrDefault(); double deltaX = currentValue.X - mousePosition.X; double deltaY = currentValue.Y - mousePosition.Y; bool dragingX = Math.Abs( deltaX ) > SystemParameters.MinimumHorizontalDragDistance; bool dragingY = Math.Abs( deltaY ) > SystemParameters.MinimumVerticalDragDistance; // If the target value is already the correct one, no need to stop animation and create another one if( ( pointAnimation != null ) && ( !dragingX && !dragingY ) ) { return; } else { if( m_ghostToMousePositionAnimationClock.CurrentState == ClockState.Active ) { // The remaining duration is the Timeline Duration less the elapsed time remainingDuration = pointAnimation.Duration.TimeSpan.Milliseconds - m_ghostToMousePositionAnimationClock.CurrentTime.Value.Milliseconds; } } } this.PauseGhostToMousePositionAnimation(); PointAnimation animation = new PointAnimation( currentAdornerPosition, mousePosition, new Duration( TimeSpan.FromMilliseconds( remainingDuration ) ) ); m_ghostToMousePositionAnimationClock = animation.CreateClock( true ) as AnimationClock; m_ghostToMousePositionAnimationClock.Completed += this.GhostToMousePosition_Completed; foreach( var adorner in this.GetElementAdorners() ) { adorner.ApplyAnimationClock( DraggedElementAdorner.OffsetProperty, m_ghostToMousePositionAnimationClock, HandoffBehavior.SnapshotAndReplace ); } m_ghostToMousePositionAnimationClock.Controller.Begin(); }
private void MoveGhostToTargetColumn( Point mousePostion ) { if( m_elementToDraggedElementAdorner.Count == 0 ) return; int remainingDuration = this.ReturnToOriginalPositionDuration; if( m_ghostToTargetColumnAnimationClock != null ) { PointAnimation pointAnimation = m_ghostToTargetColumnAnimationClock.Timeline as PointAnimation; // If the target value is already the correct one, no need to stop animation and create another one if( ( pointAnimation != null ) && ( pointAnimation.To == ColumnReorderingDragSourceManager.EmptyPoint ) ) { return; } else { if( m_ghostToTargetColumnAnimationClock.CurrentState == ClockState.Active ) { // The remaining duration is the Timeline Duration less the elapsed time remainingDuration = pointAnimation.Duration.TimeSpan.Milliseconds - m_ghostToTargetColumnAnimationClock.CurrentTime.Value.Milliseconds; } } } // We must apply the DraggedCell FadeIn animation to let the DraggedCell reappears while the ghosts are moving to their target position this.ApplyDraggedElementFadeInAnimation(); this.PauseMoveGhostToTargetColumnAnimation(); PointAnimation animation = new PointAnimation( mousePostion, ColumnReorderingDragSourceManager.EmptyPoint, new Duration( TimeSpan.FromMilliseconds( remainingDuration ) ) ); m_ghostToTargetColumnAnimationClock = animation.CreateClock( true ) as AnimationClock; m_ghostToTargetColumnAnimationClock.Completed += this.GhostToTargetAnimation_Completed; foreach( var adorner in this.GetElementAdorners() ) { adorner.ApplyAnimationClock( DraggedElementAdorner.OffsetProperty, m_ghostToTargetColumnAnimationClock, HandoffBehavior.SnapshotAndReplace ); } }
private void MoveGhostToTargetAndDetach() { if( m_elementToDraggedElementAdorner.Count == 0 ) { this.DetachManager(); return; } this.PauseMoveGhostToTargetAndDetachAnimation(); var draggedCell = this.DraggedElement as Cell; if( draggedCell == null ) return; var parentRow = draggedCell.ParentRow; if( ( parentRow == null ) || ( parentRow.CellsHostPanel == null ) ) return; var draggedAdorner = m_elementToDraggedElementAdorner[ draggedCell ]; var currentDraggedAdornerPosition = ( draggedAdorner != null ) ? draggedAdorner.Offset : default( Point ); var fromPoint = currentDraggedAdornerPosition; if( draggedAdorner != null ) { // Calculate the animation from the current ColumnManagerCell, since it could be a MergedColumnMangerCell dragging any number of columns. // If calculating the animation from a different cell, the animation could be starting from a wrong position and give a bad visual effect. var animations = this.ReorderingInfoManagerInstance.RequiredAnimations; if( animations.AnimateToLeft.Count > 0 ) { var siblingCell = parentRow.Cells[ draggedCell.ParentColumn.PreviousVisibleColumn ]; var targetPosition = siblingCell.PointToScreen( new Point( siblingCell.ActualWidth, 0d ) ); var relativePosition = draggedAdorner.PointFromScreen( targetPosition ); fromPoint = new Point( -relativePosition.X, -relativePosition.Y ); } else if( animations.AnimateToRight.Count > 0 ) { var siblingCell = parentRow.Cells[ draggedCell.ParentColumn.NextVisibleColumn ]; var targetPosition = siblingCell.PointToScreen( new Point( -draggedCell.ActualWidth, 0d ) ); var relativePosition = draggedAdorner.PointFromScreen( targetPosition ); fromPoint = new Point( -relativePosition.X, -relativePosition.Y ); } } PointAnimation animation = new PointAnimation( fromPoint, ColumnReorderingDragSourceManager.EmptyPoint, m_columnAnimationDuration ); m_ghostToTargetAndDetachAnimationClock = animation.CreateClock( true ) as AnimationClock; m_ghostToTargetAndDetachAnimationClock.Completed += this.MoveGhostToTargetAndDetach_Completed; //Animate all cells of all columns. foreach( var entry in this.GetElementAdornerEntries() ) { var cell = entry.Key as Cell; if( cell == null ) { Debug.Assert( false, "Only Cells should be dragged by this manager" ); continue; } var adorner = entry.Value; adorner.ApplyAnimationClock( DraggedElementAdorner.OffsetProperty, m_ghostToTargetAndDetachAnimationClock, HandoffBehavior.SnapshotAndReplace ); } m_ghostToTargetAndDetachAnimationClock.Controller.Begin(); }
private void MoveGhostToTargetAndDetach() { if( m_elementToDraggedElementAdorner.Count == 0 ) { this.DetachManager(); return; } this.PauseMoveGhostToTargetAndDetachAnimation(); Cell draggedCell = this.DraggedElement as Cell; if( draggedCell == null ) return; bool animationInitialized = false; DraggedElementAdorner draggedAdorner = m_elementToDraggedElementAdorner[ draggedCell ]; Nullable<Point> currentDraggedAdornerPosition = null; if( draggedAdorner != null ) { currentDraggedAdornerPosition = draggedAdorner.Offset; } foreach( UIElement element in m_elementToDraggedElementAdorner.Keys ) { Cell cell = element as Cell; if( cell == null ) { Debug.Assert( false, "Only Cells should be dragged by this manager" ); continue; } DraggedElementAdorner adorner = m_elementToDraggedElementAdorner[ element ]; if( !animationInitialized ) { TableViewColumnVirtualizationManager columnVirtualizationManager = this.DraggedDataGridContext.ColumnVirtualizationManager as TableViewColumnVirtualizationManager; if( columnVirtualizationManager == null ) return; double offset = columnVirtualizationManager.FieldNameToOffset[ draggedCell.FieldName ]; if( ( draggedCell.ParentRow == null ) || ( draggedCell.ParentRow.CellsHostPanel == null ) ) return; // Get the position of the Mouse according to the DragContainer Point mouseToDragContainer = Mouse.GetPosition( this.DragContainer ); // Get the position of the Mouse according to the DraggedElementAdorner Point adornerToMouse = Mouse.GetPosition( adorner ); // Get the position of the Cell according to the ParentRow.CellsHostPanel for the dragged Cell Panel cellsHost = cell.ParentRow.CellsHostPanel; Point newCellInCellsHostToDragContainer = cellsHost.TranslatePoint( new Point( offset, 0 ), this.DragContainer ); // Get the position of the Cell according to its CellsHost in order to know // if it was dragged from the Fixed to the Scrolling Cells. Point cellToCellsHost = cell.TranslatePoint( ColumnReorderingDragSourceManager.EmptyPoint, cell.ParentRow.CellsHostPanel ); double initialX = mouseToDragContainer.X - newCellInCellsHostToDragContainer.X - adornerToMouse.X; // The DraggedCell is a FixedCell and it offset is greater than the FixedColumnWidth if( columnVirtualizationManager.FixedFieldNames.Contains( cell.FieldName ) && ( cellToCellsHost.X > columnVirtualizationManager.FixedColumnsWidth ) ) { // In this case, we must take the HorizontalOffset into consideration initialX -= this.DraggedDataGridContext.DataGridControl.ScrollViewer.HorizontalOffset; } else { // The offset of the Cell according the CellsHost is less than 0 and // there is a Compensation offset to ensure all the ScrollingCells are // in view even if the HorizontalOffset would have scrolled them // outside the ViewPort if( ( ( newCellInCellsHostToDragContainer.X - columnVirtualizationManager.FixedColumnsWidth ) < 0 ) && ( columnVirtualizationManager.FirstColumnCompensationOffset > 0 ) ) { initialX -= columnVirtualizationManager.FirstColumnCompensationOffset; } } Point fromPoint = new Point( initialX, currentDraggedAdornerPosition.GetValueOrDefault().Y ); PointAnimation animation = new PointAnimation( fromPoint, ColumnReorderingDragSourceManager.EmptyPoint, m_columnAnimationDuration ); m_ghostToTargetAndDetachAnimationClock = animation.CreateClock( true ) as AnimationClock; m_ghostToTargetAndDetachAnimationClock.Completed += this.MoveGhostToTargetAndDetach_Completed; animationInitialized = true; } adorner.ApplyAnimationClock( DraggedElementAdorner.OffsetProperty, m_ghostToTargetAndDetachAnimationClock, HandoffBehavior.SnapshotAndReplace ); } m_ghostToTargetAndDetachAnimationClock.Controller.Begin(); }