internal void ForceUpdateGroupHeader(ListViewItem listViewItem, KeyValuePair <IGroupHeader, ExpressionAnimationItem> item) { GeneralTransform gt = listViewItem.TransformToVisual(this); var rect = gt.TransformBounds(new Rect(0, 0, listViewItem.ActualWidth, listViewItem.ActualHeight)); groupHeaderDelta = item.Key.Height; //add delta,so that it does not look like suddenly var itemMargin = new Thickness(0, rect.Top - groupHeaderDelta - defaultListViewItemMargin.Top, 0, 0); RectangleGeometry itemClip = null; Visibility itemVisibility = Visibility.Collapsed; if (itemMargin.Top < 0) { var clipHeight = groupHeaderDelta + itemMargin.Top; //moving header has part in viewport if (clipHeight > 0) { itemVisibility = Visibility.Visible; itemClip = new RectangleGeometry() { Rect = new Rect(0, -itemMargin.Top, this.ActualWidth, clipHeight) }; } //moving header not in viewport else { itemVisibility = Visibility.Collapsed; itemClip = null; } } else if (itemMargin.Top + groupHeaderDelta > this.ActualHeight) { var clipHeight = groupHeaderDelta - (groupHeaderDelta + itemMargin.Top - this.ActualHeight); //moving header has part in viewport if (clipHeight > 0) { itemVisibility = Visibility.Visible; itemClip = new RectangleGeometry() { Rect = new Rect(0, 0, this.ActualWidth, clipHeight) }; } //moving header not in viewport else { itemVisibility = Visibility.Collapsed; itemClip = null; } } //moving header all in viewport else { itemVisibility = Visibility.Visible; itemClip = null; } if (currentTopGroupHeader != null) { var delta = currentTopGroupHeader.ActualHeight - (itemMargin.Top); if (delta > 0) { currentTopGroupHeader.Margin = new Thickness(0, -delta, 0, 0); currentTopGroupHeader.Clip = new RectangleGeometry() { Rect = new Rect(0, delta, currentTopGroupHeader.ActualWidth, currentTopGroupHeader.ActualHeight) }; if (delta >= groupHeaderDelta) { currentTopGroupHeader.Visibility = Visibility.Visible; currentTopGroupHeader.Margin = new Thickness(0); currentTopGroupHeader.Clip = null; currentTopGroupHeader.DataContext = item.Key; } } } ExpressionAnimationItem expressionItem = item.Value; expressionItem.StopAnimation(); item.Value.VisualElement.Margin = itemMargin; expressionItem.VisualElement.Clip = itemClip; expressionItem.VisualElement.Visibility = itemVisibility; if (expressionItem.ScrollViewer == null) { expressionItem.ScrollViewer = scrollViewer; } expressionItem.StartAnimation(true); }
private void HandleItemsInItemsPanel(bool isIntermediate, KeyValuePair <IGroupHeader, ExpressionAnimationItem> item, ListViewItem listViewItem) { GeneralTransform gt = listViewItem.TransformToVisual(this); var rect = gt.TransformBounds(new Rect(0, 0, listViewItem.ActualWidth, listViewItem.ActualHeight)); groupHeaderDelta = item.Key.Height; //add delta,so that it does not look like suddenly var itemMargin = new Thickness(0, rect.Top - groupHeaderDelta - defaultListViewItemMargin.Top, 0, 0); RectangleGeometry itemClip = null; Visibility itemVisibility = Visibility.Collapsed; if (itemMargin.Top < 0) { var clipHeight = groupHeaderDelta + itemMargin.Top; //moving header has part in viewport if (clipHeight > 0) { itemVisibility = Visibility.Visible; itemClip = new RectangleGeometry() { Rect = new Rect(0, -itemMargin.Top, this.ActualWidth, clipHeight) }; } //moving header not in viewport else { itemVisibility = Visibility.Collapsed; itemClip = null; } } else if (itemMargin.Top + groupHeaderDelta > this.ActualHeight) { var clipHeight = groupHeaderDelta - (groupHeaderDelta + itemMargin.Top - this.ActualHeight); //moving header has part in viewport if (clipHeight > 0) { itemVisibility = Visibility.Visible; itemClip = new RectangleGeometry() { Rect = new Rect(0, 0, this.ActualWidth, clipHeight) }; } //moving header not in viewport else { itemVisibility = Visibility.Collapsed; itemClip = null; } } //moving header all in viewport else { itemVisibility = Visibility.Visible; itemClip = null; } if (currentTopGroupHeader != null) { var delta = currentTopGroupHeader.ActualHeight - (itemMargin.Top); if (delta > 0) { currentTopGroupHeader.Margin = new Thickness(0, -delta, 0, 0); currentTopGroupHeader.Clip = new RectangleGeometry() { Rect = new Rect(0, delta, currentTopGroupHeader.ActualWidth, currentTopGroupHeader.ActualHeight) }; if (delta >= groupHeaderDelta) { currentTopGroupHeader.Visibility = Visibility.Visible; currentTopGroupHeader.Margin = new Thickness(0); currentTopGroupHeader.Clip = null; currentTopGroupHeader.DataContext = item.Key; } } } bool isInViewport = false; if (itemMargin.Top > 0) { var groupheaderRect = new Rect(0, itemMargin.Top, this.ActualWidth, groupHeaderDelta); isInViewport = (groupheaderRect.Top < this.ActualHeight && groupheaderRect.Bottom > 0); } if (!isInViewport) { ClearTempElement(item); } if (!item.Value.IsActive) { // isIntermediate is false or groupheaderRect has into view port and view not changing if (!isIntermediate || (isInViewport && !isViewChanging)) { ExpressionAnimationItem expressionItem = item.Value; expressionItem.StopAnimation(); item.Value.TempElement.Margin = new Thickness(0); item.Value.TempElement.Clip = null; item.Value.TempElement.Visibility = Visibility.Collapsed; item.Value.VisualElement.Margin = itemMargin; item.Value.VisualElement.Clip = itemClip; item.Value.VisualElement.Visibility = itemVisibility; if (expressionItem.ScrollViewer == null) { expressionItem.ScrollViewer = scrollViewer; } expressionItem.StartAnimation(true); } //temp use else if (isInViewport) { item.Value.TempElement.Margin = itemMargin; item.Value.TempElement.Clip = itemClip; item.Value.TempElement.Visibility = itemVisibility; } } //use active animation else { if (item.Value.VisualElement.Clip != itemClip || item.Value.VisualElement.Visibility != itemVisibility) { ExpressionAnimationItem expressionItem = item.Value; expressionItem.StopAnimation(); if (!isIntermediate) { item.Value.VisualElement.Margin = itemMargin; } //item.Value.VisualElement.Margin = itemMargin; expressionItem.VisualElement.Clip = itemClip; expressionItem.VisualElement.Visibility = itemVisibility; if (expressionItem.ScrollViewer == null) { expressionItem.ScrollViewer = scrollViewer; } expressionItem.StartAnimation(!isIntermediate); } } }
internal void UpdateGroupHeaders(bool isIntermediate = false) { var firstVisibleItemIndex = this.GetFirstVisibleIndex(); if (firstVisibleItemIndex < 0) { return; } foreach (var item in groupDic) { //top header if (item.Key.FirstIndex <= firstVisibleItemIndex && (firstVisibleItemIndex <= item.Key.LastIndex || item.Key.LastIndex == -1)) { currentTopGroupHeader.Visibility = Visibility.Visible; currentTopGroupHeader.Margin = new Thickness(0); currentTopGroupHeader.Clip = null; currentTopGroupHeader.DataContext = item.Key; item.Value.TempElement.Visibility = Visibility.Collapsed; item.Value.TempElement.Margin = new Thickness(0); item.Value.TempElement.Clip = null; item.Value.StopAnimation(); item.Value.VisualElement.Visibility = Visibility.Collapsed; } else { ListViewItem listViewItem = ContainerFromIndex(item.Key.FirstIndex) as ListViewItem; if (listViewItem == null && item.Key.LastIndex != -1) { listViewItem = ContainerFromIndex(item.Key.LastIndex) as ListViewItem; } if (listViewItem != null) { //unloaded if (listViewItem.ActualHeight == 0 || listViewItem.ActualWidth == 0) { listViewItem.Loaded += ListViewItem_Loaded; } else { GeneralTransform gt = listViewItem.TransformToVisual(this); var rect = gt.TransformBounds(new Rect(0, 0, listViewItem.ActualWidth, listViewItem.ActualHeight)); groupHeaderDelta = item.Key.Height; //add delta,so that it does not look like suddenly if (rect.Bottom + groupHeaderDelta < 0 || rect.Top > this.ActualHeight + groupHeaderDelta) { item.Value.TempElement.Visibility = Visibility.Collapsed; item.Value.TempElement.Margin = new Thickness(0); item.Value.TempElement.Clip = null; item.Value.StopAnimation(); item.Value.VisualElement.Visibility = Visibility.Collapsed; } //in view port else { var itemMargin = new Thickness(0, rect.Top - groupHeaderDelta - defaultListViewItemMargin.Top, 0, 0); RectangleGeometry itemClip = null; Visibility itemVisibility = Visibility.Collapsed; if (itemMargin.Top < 0) { var clipHeight = groupHeaderDelta + itemMargin.Top; //moving header has part in viewport if (clipHeight > 0) { itemVisibility = Visibility.Visible; itemClip = new RectangleGeometry() { Rect = new Rect(0, -itemMargin.Top, this.ActualWidth, clipHeight) }; } //moving header not in viewport else { itemVisibility = Visibility.Collapsed; itemClip = null; } } else if (itemMargin.Top + groupHeaderDelta > this.ActualHeight) { var clipHeight = groupHeaderDelta - (groupHeaderDelta + itemMargin.Top - this.ActualHeight); //moving header has part in viewport if (clipHeight > 0) { itemVisibility = Visibility.Visible; itemClip = new RectangleGeometry() { Rect = new Rect(0, 0, this.ActualWidth, clipHeight) }; } //moving header not in viewport else { itemVisibility = Visibility.Collapsed; itemClip = null; } } //moving header all in viewport else { itemVisibility = Visibility.Visible; itemClip = null; } if (currentTopGroupHeader != null) { var delta = currentTopGroupHeader.ActualHeight - (itemMargin.Top); if (delta > 0) { currentTopGroupHeader.Margin = new Thickness(0, -delta, 0, 0); currentTopGroupHeader.Clip = new RectangleGeometry() { Rect = new Rect(0, delta, currentTopGroupHeader.ActualWidth, currentTopGroupHeader.ActualHeight) }; } } //all in viewport if (itemVisibility == Visibility.Visible) { if (!item.Value.IsActive) { //when isIntermediate is false and clip is null, so that make sure animation is accurate if (item.Value.TempElement.Clip == null && itemClip == null && !isIntermediate) { ExpressionAnimationItem expressionItem = item.Value; expressionItem.StopAnimation(); item.Value.TempElement.Visibility = Visibility.Collapsed; item.Value.TempElement.Margin = new Thickness(0); item.Value.TempElement.Clip = null; item.Value.VisualElement.Margin = itemMargin; item.Value.VisualElement.Clip = itemClip; item.Value.VisualElement.Visibility = itemVisibility; if (expressionItem.ScrollViewer == null) { expressionItem.ScrollViewer = scrollViewer; } expressionItem.StartAnimation(true); } //use tempElemnt for Clip and isIntermediate is true else { item.Value.TempElement.Margin = itemMargin; item.Value.TempElement.Clip = itemClip; item.Value.TempElement.Visibility = itemVisibility; } } //use active animation else { } } else { item.Value.TempElement.Margin = itemMargin; item.Value.TempElement.Clip = itemClip; item.Value.TempElement.Visibility = itemVisibility; item.Value.StopAnimation(); item.Value.VisualElement.Visibility = Visibility.Collapsed; } } } } else { if (item.Key != currentTopGroupHeader.DataContext) { item.Value.TempElement.Visibility = Visibility.Collapsed; item.Value.TempElement.Margin = new Thickness(0); item.Value.TempElement.Clip = null; item.Value.StopAnimation(); item.Value.VisualElement.Visibility = Visibility.Collapsed; } } } } }