WPF 2 个方向的渐变
如果我想让列表框中所选项目的边缘看起来平滑,我会这样做:
<Setter Property="Background" TargetName="Bd">
<Setter.Value>
<LinearGradientBrush EndPoint="0,0" StartPoint="1,0">
<GradientStop Offset="0" Color="Transparent"/>
<GradientStop Offset="0.05" Color="{x:Static SystemColors.HighlightColor}"/>
<GradientStop Offset="0.95" Color="{x:Static SystemColors.HighlightColor}"/>
<GradientStop Offset="1" Color="Transparent"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
但是,这只会使左侧和右侧边缘平滑,而不是顶部和底部。如果我更改 StartPoint 和 EndPoint,我可以使顶部和底部平滑,但随后我会失去左侧和右侧的平滑度。那么如何使用渐变画笔使所有 4 个边框变得平滑呢?
If i want to make the edges of a selected item in a Listbox look smooth I do this:
<Setter Property="Background" TargetName="Bd">
<Setter.Value>
<LinearGradientBrush EndPoint="0,0" StartPoint="1,0">
<GradientStop Offset="0" Color="Transparent"/>
<GradientStop Offset="0.05" Color="{x:Static SystemColors.HighlightColor}"/>
<GradientStop Offset="0.95" Color="{x:Static SystemColors.HighlightColor}"/>
<GradientStop Offset="1" Color="Transparent"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
However, this only makes the left and right edge smooth, not the top and bottom. If I change StartPoint and EndPoint, I can make the top and bottom smooth, but then I loose the smoothness on the left&right sides. So how can I make all 4 borders smooth using a Gradient brush?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正如其他人已经建议的那样,
OpacityMask
是实现此目的的一种方法,但它有点具有挑战性,因为您无法在画笔上设置OpacityMask
。您只能在视觉对象上设置它 -OpacityMask
是在每个视觉对象的基础上完成的。但是ListBox
的Background
并不是可视化树中的单独元素 - 它只是ListBox
的一个属性,而且通常是模板绑定到模板中某处的诸如Border
元素之类的内容。对于一些人在这里建议的位图效果的使用也是如此 - 这些也适用于整个视觉效果,而不是单个画笔。
但是,您可以使用 VisualBrush 来处理此问题 - 它允许您使用可视化树定义画笔。所以我认为这大致符合您的要求:
虽然角落可能不完全符合您的要求 - 取决于它们最终有多大。当你使用这种技术时,它们看起来并不特别圆。所以你可以沿着效果路线走。您可能更喜欢这样:
请注意,我使用了
Effect
而不是BitmapEffect
。Effect
的选项较少,但它们通常是更好的选择,因为它们被设计为在硬件中渲染。The
OpacityMask
is one way to do this, as others have already suggested, but it's slightly challenging because you cannot set anOpacityMask
on a brush. You can only set it on a visual -OpacityMask
is something that is done on a per-visual basis. But theBackground
of aListBox
isn't a separate element in the visual tree - it's just a property of theListBox
, and it's usually template bound to something like aBorder
element somewhere in the template.Same goes for the use of bitmap effects that some people have suggested here - those are also applied to whole visuals, not to individual brushes.
However, you can handle this with a
VisualBrush
- that lets you define a brush by using a visual tree. So I think this does roughly what you're looking for:The corners might not be quite what you're looking for though - depends on how big they end up being. They don't look especially round when you use this technique. So you could go down the effect route. You might prefer this:
Note that I've used an
Effect
rather than aBitmapEffect
. You have fewer options withEffect
, but they're usually a better option as they're designed to render in hardware.我不认为使用内置的渐变画笔可以做到这一点。
你可以实现自己的(实际上这似乎不可能,因为RectangleGradientBrush
,但我认为这并不容易......Brush
实现依赖于用户代码无法访问的低级渲染内容)I don't think it can be done with the built-in gradient brushes.
You could implement your own(actually it doesn't seem possible, asRectangleGradientBrush
, but I don't think it's easy...Brush
implementations depend on low level rendering stuff that's not accessible from user code)