【问题标题】:How do I solve this strange DropShadow issue in UWP Composition?如何解决 UWP 合成中这个奇怪的 DropShadow 问题?
【发布时间】:2018-02-03 13:07:42
【问题描述】:

在构图中使用投影时,我得到了不良效果。要复制此问题,请执行以下步骤:

第 1 步:创建一个新的 UWP 项目并定位到 Windows 10 Fall Creators Update (10.0; Build 16299)

第二步:将以下内容复制到MainPage.xaml

<Page x:Class="App1.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      mc:Ignorable="d">
    <Grid>
        <Canvas x:Name="_shadow" Width="500" Height="500" VerticalAlignment="Top" HorizontalAlignment="Left"/>

        <Canvas x:Name="_shadowSource" Width="500" Height="500" VerticalAlignment="Top" HorizontalAlignment="Left">
            <Ellipse Width="50" Height="50" Fill="DarkOrange" Canvas.Top="50" Canvas.Left="50"/>
            <Ellipse Width="50" Height="50" Fill="Aquamarine" Canvas.Top="100" Canvas.Left="100"/>
            <Ellipse Width="50" Height="50" Fill="Crimson" Canvas.Top="150" Canvas.Left="150"/>
            <Ellipse Width="50" Height="50" Fill="BlueViolet" Canvas.Top="200" Canvas.Left="200"/>
            <Ellipse Width="50" Height="50" Fill="DarkGreen" Canvas.Top="250" Canvas.Left="250"/>
            <Ellipse Width="50" Height="50" Fill="Gold" Canvas.Top="300" Canvas.Left="300"/>
            <Ellipse Width="50" Height="50" Fill="MediumAquamarine" Canvas.Top="350" Canvas.Left="350"/>
            <Ellipse Width="50" Height="50" Fill="Violet" Canvas.Top="400" Canvas.Left="400"/>
            <Ellipse Width="50" Height="50" Fill="LightSeaGreen" Canvas.Top="450" Canvas.Left="450"/>
        </Canvas>
    </Grid>
</Page>

第三步:将以下内容复制到MainPage.xaml.cs

using System.Numerics;
using Windows.UI.Composition;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Hosting;

namespace App1
{
    public sealed partial class MainPage
    {
        public MainPage()
        {
            InitializeComponent();

            var compositor = Window.Current.Compositor;
            var shadow = compositor.CreateDropShadow();
            var layer = compositor.CreateLayerVisual();

            shadow.SourcePolicy = CompositionDropShadowSourcePolicy.InheritFromVisualContent;

            layer.Shadow = shadow;
            layer.Size = new Vector2(500, 500);

            var visual = ElementCompositionPreview.GetElementVisual(_shadowSource);

            layer.Children.InsertAtBottom(visual);

            ElementCompositionPreview.SetElementChildVisual(_shadow, layer);
        }
    }
}

_shadowSource 的内容被移动到新图层,阴影设置为InheritFromVisualContent。应用加载时,您会看到阴影渲染良好,但调整应用大小会产生视觉故障。

当您注释掉 //layer.Shadow = shadow; 行时会发生以下情况

这里发生了什么?为什么阴影会导致这种情况?

【问题讨论】:

标签: c# uwp


【解决方案1】:

当您的窗口高度小于 500 时,_shadowSource 高度仍为 500,因为您的 XAML 中有 Width="500" Height="500"。所以它被剪掉了,只有上部是可见的。

但是您将阴影添加到另一个名为 _shadow 的元素中。这个没有固定大小,所以它会根据你的窗口大小调整大小,即不会发生剪裁。这就是为什么您的圆圈会扭曲为椭圆,并且您会在窗口的下部看到这些令人讨厌的伪影——如果您的阴影布局正确,图层的这些部分将被剪掉并且不可见。

【讨论】:

  • 感谢您的回答,但仍然没有什么不同。我只使用_shadow 作为视觉容器。我将其更新为具有相同的属性,但挤压效果仍然存在。
【解决方案2】:

我使用UWP Community ToolkitDropShadowPanel 控件为椭圆应用投影。效果很好。

您可以尝试以下方法:

<Page
    ...
    xmlns:control="using:Microsoft.Toolkit.Uwp.UI.Controls"
    ...
>    

<Canvas  VerticalAlignment="Top" HorizontalAlignment="Left">
        <control:DropShadowPanel BlurRadius="4.0" Canvas.Top="50" Canvas.Left="50"
                      ShadowOpacity="0.7"
                      OffsetX="5.0"
                      OffsetY="5.0"
                      Color="Black">
            <Ellipse Width="50" Height="50" Fill="DarkOrange" />
        </control:DropShadowPanel>
        <control:DropShadowPanel BlurRadius="4.0" Canvas.Top="100" Canvas.Left="100"
                      ShadowOpacity="0.7"
                      OffsetX="5.0"
                      OffsetY="5.0"
                      Color="Black">
            <Ellipse Width="50" Height="50" Fill="Aquamarine" />
        </control:DropShadowPanel>
        <control:DropShadowPanel BlurRadius="4.0" Canvas.Top="150" Canvas.Left="150"
                      ShadowOpacity="0.7"
                      OffsetX="5.0"
                      OffsetY="5.0"
                      Color="Black">
            <Ellipse Width="50" Height="50" Fill="Crimson" />
        </control:DropShadowPanel>
        <control:DropShadowPanel BlurRadius="4.0" Canvas.Top="200" Canvas.Left="200"
                      ShadowOpacity="0.7"
                      OffsetX="5.0"
                      OffsetY="5.0"
                      Color="Black">
            <Ellipse Width="50" Height="50" Fill="BlueViolet" />
        </control:DropShadowPanel>
        <control:DropShadowPanel BlurRadius="4.0" Canvas.Top="250" Canvas.Left="250"
                      ShadowOpacity="0.7"
                      OffsetX="5.0"
                      OffsetY="5.0"
                      Color="Black">
            <Ellipse Width="50" Height="50" Fill="DarkGreen" />
        </control:DropShadowPanel>
        <control:DropShadowPanel BlurRadius="4.0" Canvas.Top="300" Canvas.Left="300"
                      ShadowOpacity="0.7"
                      OffsetX="5.0"
                      OffsetY="5.0"
                      Color="Black">
            <Ellipse Width="50" Height="50" Fill="Gold" />
        </control:DropShadowPanel>
        <control:DropShadowPanel BlurRadius="4.0" Canvas.Top="350" Canvas.Left="350"
                      ShadowOpacity="0.7"
                      OffsetX="5.0"
                      OffsetY="5.0"
                      Color="Black">
            <Ellipse Width="50" Height="50" Fill="MediumAquamarine" />
        </control:DropShadowPanel>
        <control:DropShadowPanel BlurRadius="4.0" Canvas.Top="400" Canvas.Left="400"
                      ShadowOpacity="0.7"
                      OffsetX="5.0"
                      OffsetY="5.0"
                      Color="Black">
            <Ellipse Width="50" Height="50" Fill="Violet" />
        </control:DropShadowPanel>
        <control:DropShadowPanel BlurRadius="4.0" Canvas.Top="450" Canvas.Left="450"
                      ShadowOpacity="0.7"
                      OffsetX="5.0"
                      OffsetY="5.0"
                      Color="Black">
            <Ellipse Width="50" Height="50" Fill="LightSeaGreen" />
        </control:DropShadowPanel>
</Canvas>

我查看了它的源代码,我发现它会在调整应用程序窗口大小时更新阴影大小和其他东西。所以,也许,这是关键点。你可以 参考它的source code 来扩展你自己的代码。或者您可以直接使用DropShadowPanel 控件。

【讨论】:

  • 谢谢,但这些省略号是更复杂的简化示例,我无法对每个元素的阴影进行微观管理。目的是使用InheritFromVisualContent 策略为阴影效果生成统一的遮罩。最好假装不知道_shadowSource的内容。
猜你喜欢
  • 2011-11-17
  • 1970-01-01
  • 2023-01-27
  • 1970-01-01
  • 2021-07-24
  • 2012-12-10
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
相关资源
最近更新 更多