WPF gradient in two ways

If I want the edges of the selected item in the Listbox to 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 edges smooth, not the top and bottom. If I change StartPoint and EndPoint, I can make the top and bottom smooth, but then I lose the smoothness of the left and right. So, how can I make all 4 borders smooth with the Gradient brush?

+6
wpf gradient
source share
2 answers

OpacityMask is one way to do this, as others have already pointed out, but it's a bit complicated because you cannot set OpacityMask to a brush. You can install it only on a visual level - OpacityMask is something that is done for a visual basis. But the Background for the ListBox not a separate element in the visual tree - it is simply a property of the ListBox , and usually it is tied to something like a Border element somewhere in the template.

The same goes for using the raster effects that some people have suggested here - they also apply to whole visual effects, and not to individual brushes.

However, you can handle this with VisualBrush , which allows you to define a brush using a visual tree. So I think this is roughly what you are looking for:

 <Setter Property="Background" TargetName="Bd"> <Setter.Value> <VisualBrush> <VisualBrush.Visual> <Rectangle Width="1" Height="1"> <Rectangle.Fill> <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> </Rectangle.Fill> <Rectangle.OpacityMask> <LinearGradientBrush EndPoint="0,0" StartPoint="0,1"> <GradientStop Offset="0" Color="Transparent"/> <GradientStop Offset="0.05" Color="White"/> <GradientStop Offset="0.95" Color="White"/> <GradientStop Offset="1" Color="Transparent"/> </LinearGradientBrush> </Rectangle.OpacityMask> </Rectangle> </VisualBrush.Visual> </VisualBrush> </Setter.Value> </Setter> 

Angles may not be exactly what you are looking for - it depends on how big they are. They do not look particularly cool when you use this technique. This way you can go down the route of the effect. You may prefer this:

 <Setter Property="Background" TargetName="Bd"> <Setter.Value> <VisualBrush Viewbox="0.1,0.1,0.8,0.8"> <VisualBrush.Visual> <Border Width="100" Height="100" CornerRadius="10" Background="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"> <Border.Effect> <BlurEffect Radius="20"/> </Border.Effect> </Border> </VisualBrush.Visual> </VisualBrush> </Setter.Value> </Setter> 

Note that I used Effect , not BitmapEffect . You have fewer options with Effect , but they are usually the best option, as they are intended for rendering in hardware.

+5
source share

I do not think that this can be done using the built-in gradient brushes. You can implement your own RectangleGradientBrush , but I don’t think it’s easy ... (this is actually not possible, since the Brush implementation depends on low-level rendering files that are not accessible from the user code)

0
source share

All Articles