uwp GridView selectedItem 弹出窗口
Posted
技术标签:
【中文标题】uwp GridView selectedItem 弹出窗口【英文标题】:uwp GridView selectedItem Popup 【发布时间】:2018-08-09 12:16:05 【问题描述】:我正在使用 UWP 社区工具包的 AdaptiveGridView。我希望 gridview 的所选项目 在 Z 轴上弹出,这意味着所选项目必须放大到特定大小,但它不应该干扰其他 gridview 项目的大小,而是应该在画布的 Z 轴 上缩放。使用 UWP 社区工具包 scale effect 制作这种效果的可能性有哪些(但这也会影响其他项目的大小)。如果在选定的项目上不可能,在指针悬停时是否有可能?
【问题讨论】:
您尝试了哪种缩放方法?通常,比例更改不会影响布局,但大小更改会。 @JustinXL 我正在尝试解决这个问题。我使用var container = AdaptiveGridViewControl.ContainerFromIndex(AdaptiveGridViewControl.SelectedIndex) as FrameworkElement
获取所选项目的容器,并尝试使用container.Scale(2, 2, 0, 0, 500, 0, EasingType.Default)
增加比例,但它不会增加比例,但是当我更改宽度(或高度)时,它会按预期影响所选项目。为什么缩放不影响布局?
它最有可能不会改变比例,因为每个gridview项目都在一定的边界内。
对不起,我的意思是尺寸变化,这会影响布局,正如@VijayNirmal 测试的那样,由于边界,缩放不会对项目造成任何影响,我们需要一种绕过边界的方法也许在 Z 轴上?
@JustinXL 那么改变宽度(或高度)如何影响所选项目?
【参考方案1】:
方法 1:选择时更改
XAML 部分
<GridView Height="200" SelectionChanged="GridView_SelectionChanged">
<GridView.ItemTemplate>
<DataTemplate x:DataType="local:ItemSource">
<Grid Width="100" Height="100">
<!-- Content -->
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid VerticalAlignment="Center" HorizontalAlignment="Center"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
C#部分
FrameworkElement lastPopUpElement = null;
private void GridView_SelectionChanged(object sender, SelectionChangedEventArgs e)
if (lastPopUpElement != null)
Canvas.SetZIndex(lastPopUpElement, 0);
lastPopUpElement.Scale(centerX: 50, centerY: 50, easingType: EasingType.Sine).Start();
lastPopUpElement = (sender as GridView).ContainerFromIndex((sender as GridView).SelectedIndex) as FrameworkElement;
if (lastPopUpElement != null)
Canvas.SetZIndex(lastPopUpElement, 1);
lastPopUpElement.Scale(scaleX: 1.5f, scaleY: 1.5f, centerX: 50, centerY: 50, easingType: EasingType.Sine).Start();
样本输出
方法二:指针悬停
XAML 部分
<GridView Height="200">
<GridView.ItemTemplate>
<DataTemplate x:DataType="local:ItemSource">
<Grid Width="100" Height="100" PointerEntered="GridView_PointerEntered" PointerExited="GridView_PointerExited">
<!-- Content -->
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid VerticalAlignment="Center" HorizontalAlignment="Center"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
C#部分
FrameworkElement lastPopUpElement = null;
private void GridView_PointerEntered(object sender, PointerRoutedEventArgs e)
lastPopUpElement = VisualTreeHelper.GetParent(VisualTreeHelper.GetParent(sender as FrameworkElement) as FrameworkElement) as FrameworkElement;
Canvas.SetZIndex(lastPopUpElement, 1);
lastPopUpElement.Scale(scaleX: 1.5f, scaleY: 1.5f, centerX: 50, centerY: 50, easingType: EasingType.Sine).Start();
private void GridView_PointerExited(object sender, PointerRoutedEventArgs e)
if (lastPopUpElement != null)
Canvas.SetZIndex(lastPopUpElement, 0);
lastPopUpElement.Scale(centerX: 50, centerY: 50, easingType: EasingType.Sine).Start();
样本输出
方法 3:使用投影
XAML 部分
<GridView Height="200">
<GridView.ItemTemplate>
<DataTemplate x:DataType="local:ItemSource">
<controls:DropShadowPanel OffsetX="5" OffsetY="5" Color="Black" BlurRadius="5" ShadowOpacity="0" PointerEntered="myListView_PointerEntered" PointerExited="myListView_PointerExited">
<Grid Width="100" Height="100" VerticalAlignment="Center" HorizontalAlignment="Center">
<!-- Content -->
</Grid>
</controls:DropShadowPanel>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid VerticalAlignment="Center" HorizontalAlignment="Center"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
C#部分
private void myListView_PointerEntered(object sender, PointerRoutedEventArgs e)
DropShadowPanel DropShadow = sender as DropShadowPanel;
lastPopUpElement = VisualTreeHelper.GetParent(VisualTreeHelper.GetParent(DropShadow) as FrameworkElement) as FrameworkElement;
DropShadow.ShadowOpacity = 0.5;
Canvas.SetZIndex(lastPopUpElement, 10);
lastPopUpElement.Scale(scaleX: 1.5f, scaleY: 1.5f, centerX: 50, centerY: 50, easingType: EasingType.Sine).Start();
private void myListView_PointerExited(object sender, PointerRoutedEventArgs e)
if (lastPopUpElement != null)
DropShadowPanel DropShadow = sender as DropShadowPanel;
DropShadow.ShadowOpacity = 0;
Canvas.SetZIndex(lastPopUpElement, 0);
lastPopUpElement.Scale(centerX: 50, centerY: 50, easingType: EasingType.Sine).Start();
样本输出
(旧帖)
方法一(不与其他物品叠加)
XAML 部分
<Grid Name="MainGrid" Height="200">
<controls:AdaptiveGridView x:Name="myAdaptiveGridView" SelectionChanged="myAdaptiveGridView_SelectionChanged" VerticalAlignment="Center" HorizontalAlignment="Left">
<controls:AdaptiveGridView.ItemTemplate>
<DataTemplate>
<Grid Width="150" Height="150">
<Grid Width="100" Height="100" VerticalAlignment="Center" HorizontalAlignment="Center">
<!-- Content -->
</Grid>
</Grid>
</DataTemplate>
</controls:AdaptiveGridView.ItemTemplate>
</controls:AdaptiveGridView>
</Grid>
C#部分
FrameworkElement oldSetectedItem = null;
private void myAdaptiveGridView_SelectionChanged(object sender, SelectionChangedEventArgs e)
if (oldSetectedItem != null)
oldSetectedItem.Scale(1, 1, 50, 50, 500).Start();
var container = myAdaptiveGridView.ContainerFromIndex(myAdaptiveGridView.SelectedIndex) as FrameworkElement;
var listViewItemPresenter = VisualTreeHelper.GetChild(container, 0) as FrameworkElement;
var outerGrid = VisualTreeHelper.GetChild(listViewItemPresenter, 0) as FrameworkElement;
var grid = VisualTreeHelper.GetChild(outerGrid, 0) as FrameworkElement;
oldSetectedItem = grid;
grid.Scale(1.5f, 1.5f, 50, 50, 500).Start();
样本输出
方法二(会与其他物品叠加)
XAML 部分
<Grid Name="MainGrid" Height="200">
<controls:AdaptiveGridView x:Name="myAdaptiveGridView" SelectionChanged="myAdaptiveGridView_SelectionChanged" VerticalAlignment="Center" HorizontalAlignment="Left">
<controls:AdaptiveGridView.ItemTemplate>
<DataTemplate>
<Grid Width="100" Height="100" VerticalAlignment="Center" HorizontalAlignment="Center">
<!-- Content -->
</Grid>
</DataTemplate>
</controls:AdaptiveGridView.ItemTemplate>
</controls:AdaptiveGridView>
<Image x:Name="RenderedImage" Stretch="None" Visibility="Collapsed" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</Grid>
C#部分
private async void myAdaptiveGridView_SelectionChangedAsync(object sender, SelectionChangedEventArgs e)
RenderedImage.Scale(1, 1, 0, 0, 0).Start();
var container = myAdaptiveGridView.ContainerFromIndex(myAdaptiveGridView.SelectedIndex) as FrameworkElement;
var listViewItemPresenter = VisualTreeHelper.GetChild(container, 0) as FrameworkElement;
var grid = VisualTreeHelper.GetChild(listViewItemPresenter, 0) as FrameworkElement;
oldSetectedItem = grid;
var TTV = grid.TransformToVisual(MainGrid);
Point screenCoords = TTV.TransformPoint(new Point(0, 0));
RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(grid);
RenderedImage.Source = renderTargetBitmap;
RenderedImage.Margin = new Thickness(screenCoords.X, screenCoords.Y, 0, 0);
RenderedImage.Width = grid.ActualWidth;
RenderedImage.Height = grid.ActualHeight;
RenderedImage.Visibility = Visibility.Visible;
RenderedImage.Scale(1.5f, 1.5f, 50, 50, 500).Start();
样本输出
【讨论】:
这是一个绝妙的答案,干得好@VijayNirmal 我认为我们还可以添加阴影效果,这将改善叠加效果,但您已经完成了核心任务,非常感谢 :) 顺便说一下在第二种方法中,为什么你把外网格的高度设置为150?我猜它也可以使用 100 高度,因为它应该覆盖 @JustinXL 谢谢 @touseef 是的。你可以删除它。我将编辑我的答案。 我在 UWPCommunityToolkit 中打开了一个issue 来创建一个弹出动画。以上是关于uwp GridView selectedItem 弹出窗口的主要内容,如果未能解决你的问题,请参考以下文章