UWP 透明 LinearGradientBrush
UWP transparent LinearGradientBrush
我的 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>
此代码片段应在页面底部显示一个透明叠加层,但它却创建了一个黑色叠加层,就像它在现有背景(也是彩色背景)上添加透明值一样stdBackgroundColor
) 因此看起来很奇怪(见下图)
如何在没有这种效果的情况下实现对内容(例如ScrollViewer
)的透明覆盖?
免责声明,我在工作,无法访问可以测试此代码的平台,但根据我的查找,它应该可以工作。
潜在的问题是颜色混合之一,即我们想要从全 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 以使用不透明度 属性 而不是颜色 #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"/>
问题是如果你想让混合只影响不透明度,其余颜色必须相同。您将看到一条起始颜色逐渐淡入并变为结束颜色的带。
我的 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>
此代码片段应在页面底部显示一个透明叠加层,但它却创建了一个黑色叠加层,就像它在现有背景(也是彩色背景)上添加透明值一样stdBackgroundColor
) 因此看起来很奇怪(见下图)
如何在没有这种效果的情况下实现对内容(例如ScrollViewer
)的透明覆盖?
免责声明,我在工作,无法访问可以测试此代码的平台,但根据我的查找,它应该可以工作。
潜在的问题是颜色混合之一,即我们想要从全 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 以使用不透明度 属性 而不是颜色 #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"/>
问题是如果你想让混合只影响不透明度,其余颜色必须相同。您将看到一条起始颜色逐渐淡入并变为结束颜色的带。