Reputation: 1420
My task is pretty simple: draw a line from point A to point B and set different colors at point A and B, e.g. White at A and Black at B to fade out the line.
I tried doing this using a LinearGradientBrush:
var brush = new LinearGradientBrush(
Color.FromArgb(255, 0, 0, 0),
Color.FromArgb(255, 255, 0, 0), new Point(0, 0), new Point(1,1));
var pen = new Pen(brush, 10.0);
dc.DrawLine(pen, new Point (300, 300), new Point(300, 100));
But this does not produce the wanted results since the GradientBrush is mapped according to the bounding box of the object. Therefore, the results for line going from 100/100 to 200/200 and a line going the opposite direction are the same (which is not what I want).
How could I solve this using WPF? Thanks.
Edit: I need to use the low level graphics functions (such as DrawLine) for performance reasons because I draw a lot of lines.
Upvotes: 0
Views: 5735
Reputation: 8940
How to use a LinearGradientBrush article with examples in both XAML and C# code.
Try this approach and please tell me is that what you need. Take attention please that this lines are drawn in opposite directions.
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
var image = new Image
{
Source = new DrawingImage(CreateDrawingVisualRectangle(new Point(300,300), new Point(300,100) ).Drawing),
Stretch = Stretch.None,
};
var image2 = new Image
{
Margin = new Thickness(10, 0, 0, 0),
Source = new DrawingImage(CreateDrawingVisualRectangle(new Point(300, 100), new Point(300, 300)).Drawing),
Stretch = Stretch.None,
};
var stackPanel = new StackPanel() {Orientation = Orientation.Horizontal};
stackPanel.Children.Add(image);
stackPanel.Children.Add(image2);
Content = stackPanel;
}
// Create a DrawingVisual that contains a rectangle.
private DrawingVisual CreateDrawingVisualRectangle(Point start, Point end)
{
DrawingVisual drawingVisual = new DrawingVisual();
// Retrieve the DrawingContext in order to create new drawing content.
DrawingContext drawingContext = drawingVisual.RenderOpen();
// Create a rectangle and draw it in the DrawingContext.
var gradientStopCollection = new GradientStopCollection
{
new GradientStop(Color.FromArgb(255, 0, 0, 0), 0.0),
new GradientStop(Color.FromArgb(255, 255, 0, 0), 0.75)
};
var brush = new LinearGradientBrush(gradientStopCollection);
var pen = new Pen(brush, 10.0);
var vector1 = new Vector(start.X, start.Y);
var vector2 = new Vector(end.X, end.Y);
if (vector1.Length < vector2.Length)
{
brush.StartPoint = new Point(1, 1);
brush.EndPoint = new Point(0, 0);
}
drawingContext.DrawLine(pen, start, end);
drawingContext.Close();
return drawingVisual;
}
}
Upvotes: 1
Reputation: 3625
How about using a rectangle?
<Rectangle Height="2" Margin="10,0,10,10">
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="Transparent" Offset="1.0"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
Upvotes: 3
Reputation: 70142
The MappingMode property on the brush allows you to specify absolute coordinates for the start / end points, or coordinates relative to the shapes bounds:
http://msdn.microsoft.com/en-us/library/system.windows.media.gradientbrush.mappingmode.aspx
Upvotes: 0