【问题标题】:UWP. How To Implement drop shadow in code without using DropShadowPanel inUWP。如何在代码中实现投影而不使用 DropShadowPanel
【发布时间】:2020-02-27 01:14:12
【问题描述】:

我不是使用 Windows 组合 API 的专家。如何在 UWP 中的控件或布局或任何可视控件上实现 DropShadow,而不出于某些目的使用 DropShadowPanel。一个附加的例子会很棒。另外请确保阴影效果在控件后面并且不会覆盖它

【问题讨论】:

  • DropShadowPanel 是开源 Windows 社区工具包的一部分。您可以在github.com/Microsoft/WindowsCommunityToolkit/tree/master/… 查看它的源代码以了解它是如何实现的
  • 我根据自己对UWP DropShadowControl机制的理解写了一段代码。这是块:block
  • 但是没有被应用
  • 那么我的代码有什么问题吗?

标签: uwp styling dropshadow dropshadoweffect


【解决方案1】:

在您的代码中,您已经从控件的 Compositor 创建了一个SpriteVisual 并配置了SpriteVisual 的阴影,但是您没有将这个名为shadowVisualSpriteVisual 设置为视觉树的一个孩子,这样您就看不到要应用的阴影。您可以将以下代码放在代码块的末尾。

...
ElementCompositionPreview.SetElementChildVisual(Control, shadowVisual);

您的代码将如下所示:

//Control is the control the shadow is applied to. e.g. Button, TextBlock etc.
Compositor compositor = ElementCompositionPreview.GetElementVisual(Control).Compositor;
var shadowVisual = compositor.CreateSpriteVisual();
var dropShadow = compositor.CreateDropShadow();
shadowVisual.Shadow = dropShadow;

//UpdateShadowSize
Vector2 newSize = new Vector2(0, 0);
if (Control is FrameworkElement contentFE)
{
    newSize = new Vector2((float)contentFE.ActualWidth, (float)contentFE.ActualHeight);
    //newSize = new Vector2(200, 60);
}
shadowVisual.Size = newSize;

//Some hardcoded values for now
dropShadow.BlurRadius = 8;
dropShadow.Opacity = 0.3f;
dropShadow.Offset = new Vector3(new Vector2(2, 2), 0);
dropShadow.Color = Windows.UI.Colors.Black;

// Sets a Visual as child of the Control’s visual tree.
ElementCompositionPreview.SetElementChildVisual(Control, shadowVisual);

注意:我将dropShadow.Opacity 更改为0.3f 以使阴影更清晰。

---更新---

是的,您可以在 MainContent 后面放置一个特殊元素,然后从该元素创建阴影以在 Main 内容后面制作阴影。 GetAlphaMask 方法应该可以,这里有一个例子,你可以试试。

xaml:

<Grid Loaded="Grid_Loaded">
    <!-- Canvas to create shadow-->
    <Canvas Name="canvas"/>
    <TextBlock x:Name="textBlcok" Text="this is text blcok for test shadow"/>
</Grid>

后面的代码:

private void Grid_Loaded(object sender, RoutedEventArgs e)
{
    //The canvas is the element to create shadow
    var compositor = ElementCompositionPreview.GetElementVisual(canvas).Compositor;
    var dropShadow = compositor.CreateDropShadow();
    dropShadow.Color = Colors.Green;
    dropShadow.BlurRadius = 8;
    dropShadow.Opacity = 20.0f;
    dropShadow.Offset = new Vector3(2.5F, 2.5F, 0);

    //The textBlock is the main content
    var mask = textBlcok.GetAlphaMask();
    dropShadow.Mask = mask;

    var spriteVisual = compositor.CreateSpriteVisual();
    spriteVisual.Size = new Vector2((float)canvas.ActualWidth, (float)canvas.ActualHeight);

    spriteVisual.Shadow = dropShadow;

    ElementCompositionPreview.SetElementChildVisual(canvas, spriteVisual);
}

【讨论】:

  • 我发现了这一点并应用了阴影,但我覆盖了元素。所以在 MainContent 后面做了一个特殊的元素,叫做 ShadowElement。现在我在主要内容后面应用了阴影,这就是我们想要的。
  • 我面临的另一个问题是面具。 UWP DropShadowPanel 使用 GetAlphaMask 为形状和文本获取特定类型的阴影。我使用相同的代码,但它不起作用
  • 我已经在示例代码中添加了 update 部分,您可以尝试使用 GetAlphaMask 方法。如果删除设置遮罩的代码,您将看到阴影将应用于所有画布范围。
【解决方案2】:

https://www.microsoft.com/en-us/p/windows-community-toolkit-sample-app/9nblggh4tlcq

这个应用程序包含许多控件来构建一个漂亮的 uwp 应用程序,它有一个影子库,您可以看到如何在您的项目中实现它并为您提供任何控件的影子

【讨论】:

    猜你喜欢
    • 2022-11-24
    • 2018-01-05
    • 1970-01-01
    • 1970-01-01
    • 2019-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-03
    相关资源
    最近更新 更多