开发者

Custom Brush - I want two gradients chaining them together

开发者 https://www.devze.com 2022-12-30 12:23 出处:网络
I am making a bar chart and I want two separate gradients for each bar. First I want a gradient to go from top to bottom solid red to transparent red. I want to paint over the top of that a gradient t

I am making a bar chart and I want two separate gradients for each bar. First I want a gradient to go from top to bottom solid red to transparent red. I want to paint over the top of that a gradient that goes from right to left, black to opaque.

So - In the bottom left we should have;

  • Bottom left - Alpha 0
  • Bottom right - Alpha 0
  • Top left - Alpha 255 Colour Red
  • Top Right - Alpha 255 Colour Black

So in effect I want to take a solid colour, add a left to right gradient to black then take the output of that and add a top to bottom gradient to transparency.

开发者_如何学编程All this and I want it to be in a single brush, is this even possible?


Yes. Use a VisualBrush whose Visual is a Rectangle inside a Border to combine the other two brushes.

Something like this:

<LinearGradientBrush x:Key="UnderBrush" EndPoint="0,1"> 
  <GradientStop Color="#FFFF0000" Offset="0" /> 
  <GradientStop Color="#00FF0000" Offset="1" /> 
</LinearGradientBrush> 

<LinearGradientBrush x:Key="OverBrush" EndPoint="1,0"> 
  <GradientStop Color="#00000000" Offset="0" /> 
  <GradientStop Color="#FF000000" Offset="1" /> 
</LinearGradientBrush> 

<VisualBrush x:Key="CombinedBrush">
  <VisualBrush.Visual>
    <Border Background="{StaticResource UnderBrush}">
      <Rectangle Fill="{StaticResource OverBrush}" Width="1" Height="1" />
    </Border>
  </VisualBrush.Visual>
</VisualBrush>

CombinedBrush can be used to paint your bars, and you will get the effect you describe.

Silverlight version

Since Silverlight has no VisualBrush you must build a WritableBitmap in code and use it with an ImageBrush:

<ImageBrush x:Key="CombinedBrush">
  <my:VisualBrushSimulator.Visual>
    <Border Background="{StaticResource UnderBrush}">
      <Rectangle Fill="{StaticResource OverBrush}" Width="1" Height="1" />
    </Border>
  </my:VisualBrushSimulator.Visual>
</ImageBrush>

Here is how the VisualBrushSimulator might be implemented:

public class VisualBrushSimulator : DependencyObject
{
  public Visual GetVisual(DependencyObject obj) { return (Visual)obj.GetValue(VisualProperty); }
  public void SetVisual(DependencyObject obj, Visual value) { obj.SetValue(VisualProperty, value); }
  public static readonly DependencyProperty VisualProperty = DependencyProperty.RegisterAttached("Visual", typeof(Visual), typeof(VisualBrushSimulator), new PropertyMetadata
  {
    PropertyChangedCallback = (obj, e) =>
    {
      int width=1000;
      int height=1000;
      var bitmap = new WritableBitmap(width, height);
      bitmap.Render((Visual)e.NewValue, new ScaleTransform { ScaleX = width, ScaleY = height });
      ((ImageBrush)obj).ImageSource = bitmap;
    }
  });
}

Note that this is not a true VisualBrush simulation, since changes to the Visual do not affect the brush.


If the template for your bar is based on Grids, you could then overlay the 2 gradients as below. I am not sure I fully understood what you wanted for your 2nd gradient, but I assume you mean left-to-right, transparent black to solid black. If I misunderstood, it is easy to change the 2nd gradient in the XAML below.

<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid Width="100" Height="300" >
        <Grid>
            <Grid.Background>
                <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                    <GradientStop Color="#FFFF0000" Offset="0" />
                    <GradientStop Color="#00FF0000" Offset="1" />
                </LinearGradientBrush>
            </Grid.Background>
        </Grid>
        <Grid>
            <Grid.Background>
                <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
                    <GradientStop Color="#00000000" Offset="0" />
                    <GradientStop Color="#FF000000" Offset="1" />
                </LinearGradientBrush>
            </Grid.Background>
        </Grid>
    </Grid>
</UserControl>

Paste this XAML into Charles Petzold's XAML Cruncher to see the results.

Good luck,
Jim McCurdy
Face to Face Software and YinYangMoney

0

精彩评论

暂无评论...
验证码 换一张
取 消