【问题标题】:UWP transparent LinearGradientBrushUWP 透明 LinearGradientBrush
【发布时间】:2016-02-01 15:58:06
【问题描述】:

我的 c# UWP 应用程序出现问题。

<Grid VerticalAlignment="Bottom" Height="40" Grid.Row="3" Margin="0,0,0,-1">
  <Grid.Background>
    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
        <GradientStop Color="#00000000" Offset="0"/>
        <GradientStop Color="{StaticResource stdBackgroundColor}" Offset="1"/>
    </LinearGradientBrush>
  </Grid.Background>
</Grid>

这段代码 sn-p 应该在页面底部显示一个透明覆盖,但它会创建一个黑色覆盖,就像它在现有背景之上添加透明值(也是颜色 stdBackgroundColor)因此看起来很奇怪(见下图)

如何在没有这种效果的情况下实现内容的透明叠加(例如ScrollViewer)?

【问题讨论】:

  • 这看起来有点滑稽,我不确定我是否正确地可视化了您的预期输出。由于您在第一个偏移量上将 alpha 设置为 0,并且我不确定 stdBackgroundColor 是什么,因此您是否有示例说明您想要的效果是什么?
  • 图片中的预期输出应该是,什么都看不到,但一切都一样Color(在本例中是stdBackgroundColor,即#FFa1a1a1)。当上方的 Grid 后面有内容时,该内容应该慢慢淡入背景颜色 (stdBackgroundColor)。

标签: c# xaml uwp transparent linear-gradients


【解决方案1】:

免责声明,我在工作,无法访问可以测试此代码的平台,但根据我查找的内容,它应该可以工作。

潜在的问题是颜色混合之一,即我们希望从完整的 alpha 平滑地混合到任意颜色。从Color.Transparent 开始的问题是,当 Alpha 通道比其他组件进展得更多时,您会得到一条白色带。 #00000000 也会出现类似的问题,因为它有一条黑色带。解决方案是从不透明度设置为0 的颜色版本开始。根据您正在开发的基于 XAML 的应用程序的版本,我们处理此问题的方式略有不同——我发现很难保持直截了当。在 UWP 中,我们没有不透明蒙版,也无法单独在不透明度上创建渐变。唯一剩下的就是使用 IValueConverter。

GradientStop 中的Color 属性是Color 而不是Brush,因为这会使渲染系统过于复杂。所以我们需要的第一步是一个IValueConverter,它接受任何Color并去掉alpha值:

public class TransparentColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType,
                          object parameter, string language)
    {
        Color convert = (Color) value; // Color is a struct, so we cast
        return Color.FromArgb(0, convert.R, convert.G, convert.B);
    }

    public object ConvertBack(object value, Type targetType,
                              object parameter, string language)
    {
         throw new NotImplementedException();
    }
}

下一个挑战是创建一个我们可以使用此颜色的绑定。绑定对象允许我们指定一个Source,它可以是我们传入的任何对象。ElementName 不起作用,因为资源是通过键而不是名称来引用的。

<LinearGradientBrush x:Key="OpacityGradientBrush" StartPoint="0,0" EndPoint="0,1">
  <GradientStop Color="{Binding Source={StaticResource stdBackgroundColor},
                       Converter={StaticResource TransparentColorConverter}}" Offset="0"/>
  <GradientStop Color="{StaticResource stdBackgroundColor}" Offset="1"/>
</LinearGradientBrush>

当然,不要忘记将TransparentColorConverter 放在您的Resources 中,以便您可以在此处引用。就个人而言,我宁愿不必使用转换器,但在这种情况下,我认为这是有道理的。

注意:我们在绑定中使用Source,因此我们可以引用静态资源。如果我们有一个可以绑定的属性,我们可以改用Path


以下答案适用于 WPF,但不适用于 UWP。我希望微软停止以不兼容的方式重新定义相同的概念,但这就是我们生活的世界。

根据this answer更正我的答案

您想要更改 LinearGradientBrush 以使用 Opacity 属性而不是颜色 #00000000。问题是它正在从基本黑色插入到您想要的颜色。要获得您想要的效果,您需要像这样设置不透明蒙版画笔:

<LinearGradientBrush x:Key="OpacityGradientBrush" StartPoint="0,0" EndPoint="0,1">
  <GradientStop Color="#00FFFFFF" Offset="0"/>
  <GradientStop Color="#FFFFFFFF" Offset="1"/>
</LinearGradientBrush>

然后在您需要应用不透明蒙版的代码中,您可以像这样引用它:

<Grid VerticalAlignment="Bottom" Height="40" Grid.Row="3"
    Background="{StaticResource stdBackgroundColor}"
    OpacityMask="{StaticResource OpacityGradientBrush} Margin="0,0,0,-1"/>

问题在于,如果您希望混合仅影响不透明度,则其余颜色必须相同。你会得到一个带你的起始颜色淡入并改变为结束颜色,否则。

【讨论】:

  • 这听起来很合理,但不幸的是我收到了一个错误,即The property 'Opacity' was not found in type 'GradientStop'. ,那么您是如何在LinearGradientBrush 中实现Opacity 的?
  • 我已经更改了代码以提供相同的效果,但没有在渐变停止中使用不透明度。希望这对你有用。关于颜色混合的 cmets 仍然适用,我没有更改。
  • 不幸的是,您链接到的答案仅适用于 WPF,但不适用于 c# UWP 应用程序。在 UWP 中没有OpacityMask(还没有)
  • 我现在唯一能想到的就是使用 ValueConverter 获取颜色并删除 alpha(将 alpha 设置为 0 并将 RGB 值复制到新颜色)。这当然只适用于起始值。为什么微软不能只有一个 API?很难弄清楚哪种 XAML 风格中有哪些功能。
  • 特别是对于 OpacityMask,我还没有观看视频,但现在可能有办法,因为这是在 Channel9 上:如何使用 Direct2D 将不透明蒙版应用于通用应用程序中的图像channel9.msdn.com/Blogs/OneCode/…跨度>
猜你喜欢
  • 2012-03-17
  • 1970-01-01
  • 2016-10-12
  • 1970-01-01
  • 2017-05-04
  • 2017-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多