UWP中GridView项内图片缩放后被遮挡,如何置于顶层?
这个问题我之前也碰到过,本质就是UWP元素的Z顺序渲染规则在搞鬼——默认情况下,XAML里先声明的元素会被后声明的元素覆盖,而RenderTransform只是改变元素的视觉大小和位置,不会自动提升它的Z层级。下面给你几个靠谱的解决方案,按从简单到灵活的顺序来:
1. 调整XAML元素的声明顺序(最简单)
UWP的渲染逻辑是「先定义的在底层,后定义的在顶层」。如果你的图片现在被GridView项里的其他元素(比如你代码里的BorderRectangle)挡住,直接把图片元素移到所有可能遮挡它的元素后面就行。
比如原来的模板结构可能是:
<Grid> <!-- 先定义的Border会在顶层,挡住后面的图片 --> <Border x:Name="BorderRectangle" Opacity="0" ... /> <Image x:Name="MyScaledImage" ... /> </Grid>
改成:
<Grid> <Image x:Name="MyScaledImage" ... /> <!-- 后定义的Border会在图片下方,不会遮挡 --> <Border x:Name="BorderRectangle" Opacity="0" ... /> </Grid>
这样不用额外加属性,就能让图片始终在顶层,缩放后自然不会被挡住。
2. 使用Canvas.ZIndex附加属性(最灵活)
如果不想调整XAML结构,或者需要动态控制Z层级,就给你的图片设置一个更高的Canvas.ZIndex值——这个属性可以强制改变元素的渲染优先级,数值越大越靠上。比如:
<Image x:Name="MyScaledImage" Canvas.ZIndex="10" ...> <Image.RenderTransform> <ScaleTransform x:Name="contentborderscale" ScaleX="1" ScaleY="1" /> </Image.RenderTransform> </Image>
同时,确保那些可能遮挡的元素(比如BorderRectangle)的ZIndex低于这个值(默认是0,所以只要设成比0大就行)。就算在PointerOver状态下显示BorderRectangle,它也会在图片下方。
3. 检查GridViewItem的默认视觉元素
如果上面两种方法都没用,可能是GridViewItem自带的默认视觉层(比如选中状态的高亮、焦点框)在捣乱。这时候可以自定义GridViewItem的样式,把那些默认的高亮元素的ZIndex调低,或者在你的图片元素上设置更高的ZIndex。
另外补充个小细节:你用ObjectAnimationUsingKeyFrames来设置ScaleY,其实对于数值类型的属性(比如ScaleTransform的ScaleX/Y),用DoubleAnimation会更流畅,比如:
<VisualState x:Name="PointerOver"> <Storyboard> <DoubleAnimation Duration="0" Storyboard.TargetName="BorderRectangle" Storyboard.TargetProperty="Opacity" To="1" /> <DoubleAnimation Duration="0:0:0.2" Storyboard.TargetName="contentborderscale" Storyboard.TargetProperty="ScaleY" To="1.2" /> <DoubleAnimation Duration="0:0:0.2" Storyboard.TargetName="contentborderscale" Storyboard.TargetProperty="ScaleX" To="1.2" /> </Storyboard> </VisualState>
这样缩放会有过渡动画,体验会更好。
内容的提问来源于stack exchange,提问作者Roshmi Benny

