阴影在文本上方

Drop shadow is above the text

我正在向 Xamarin.UWP 项目添加阴影(但这个问题并不是真正特定于 Xamarin,而是一般的 UWP):

bool IsShadowSupported => ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 3); // SDK >= 14393

if (IsShadowSupported) {
  var compositor = ElementCompositionPreview.GetElementVisual(Control).Compositor;
  dropShadow = compositor.CreateDropShadow();
  if (Control is Windows.UI.Xaml.Controls.TextBlock textBlock)
    dropShadow.Mask = textBlock.GetAlphaMask();
  shadowVisual = compositor.CreateSpriteVisual();
  shadowVisual.Shadow = dropShadow;
  ElementCompositionPreview.SetElementChildVisual(Control, shadowVisual);
  ...
  dropShadow.Offset = new Vector3((float)Shadow.GetDistanceX(Element), (float)Shadow.GetDistanceY(Element), -5f);
}

它运行并出现阴影——但在文本上方,而不是在其下方。起初我认为这将由偏移的 Z 坐标决定,但没有负值、正值或零值会改变任何东西。阴影看起来像这样:

这本身并不是一个坏效果,但它不是所要求的:白色文本和其下方的深灰色阴影。

问题是 SetElementChildVisual 将视觉设置为给定元素的最后一个子元素,这将使阴影出现在 TextBlock 上方。不幸的是,即使是 TextBlock 的父元素也不够,您应该有一个相邻的元素来承载阴影:

<Grid x:Name="ShadowHost" />
<TextBlock x:Name="Hello" Text="Hello" />

现在在您的代码中使用 ShadowHost 而不是 Control,除了 GetAlphaMask 调用之外您应该使用 TextBlock

当然,要使阴影发挥作用,这是一项相当大的工作,这就是为什么您可以尝试使用 Windows 社区工具包的 DropShadowPanel 的原因 - 请参阅 documentation 了解更多信息。