WPF新手。我需要绘制一条线(在网格内部"单元格",如果这有所不同),其开始/结束上限与线本身颜色不同。似乎在线上获得上限很容易;让它成为一种不同的颜色并不是那么简单。
我查看了Line,PolyLine,Pen,Path,LineGeometry和EllipseGeometry对象。所有这些似乎都为我的问题提供了部分解决方案。 This文章似乎最接近解决方案,但代码示例不完整。
很高兴接受我的问题的任何建议或解决方案。
答案 0 :(得分:0)
这是一个想法......使用线性渐变画笔
draw
答案 1 :(得分:0)
你可以自己动手。这是我找到并修改以满足我的需求的代码。 我添加了 CapStroke 和 CapStrokeThickness 属性
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
namespace LineCaps
{
public class CappedLine: FrameworkElement
{
protected override void OnRender(DrawingContext dc)
{
Point pos, tangent;
double angleInRadians;
double angleInDegrees;
TransformGroup tg;
Pen pen = new Pen(Stroke, StrokeThickness);
dc.DrawGeometry(null, pen, LinePath);
Pen capPen = new Pen(CapStroke, CapStrokeThickness);
if (BeginCap != null)
{
LinePath.GetPointAtFractionLength(0.01d, out pos, out tangent);
angleInRadians = Math.Atan2(tangent.Y, tangent.X) + Math.PI;
angleInDegrees = angleInRadians * 180 / Math.PI + 180;
tg = new TransformGroup();
tg.Children.Add(new RotateTransform(angleInDegrees));
LinePath.GetPointAtFractionLength(0.0d, out pos, out tangent);
tg.Children.Add(new TranslateTransform(pos.X, pos.Y));
dc.PushTransform(tg);
dc.DrawGeometry(CapStroke, capPen, BeginCap);
dc.Pop();
}
if (EndCap != null)
{
LinePath.GetPointAtFractionLength(0.99, out pos, out tangent);
angleInRadians = Math.Atan2(tangent.Y, tangent.X) + Math.PI;
angleInDegrees = angleInRadians * 180 / Math.PI;
tg = new TransformGroup();
tg.Children.Add(new RotateTransform(angleInDegrees));
LinePath.GetPointAtFractionLength(1, out pos, out tangent);
tg.Children.Add(new TranslateTransform(pos.X, pos.Y));
dc.PushTransform(tg);
dc.DrawGeometry(CapStroke, capPen, EndCap);
}
}
protected override Size MeasureOverride(Size availableSize)
{
//TODO: Consider creating the Pen once when Stroke and StrokeThickness are set
return LinePath.GetRenderBounds(new Pen(Stroke, StrokeThickness)).Size;
}
public static readonly DependencyProperty StrokeProperty = Shape.StrokeProperty.AddOwner(typeof(CappedLine));
public Brush Stroke
{
get { return (Brush)GetValue(StrokeProperty); }
set { SetValue(StrokeProperty, value); }
}
public static readonly DependencyProperty StrokeThicknessProperty = Shape.StrokeThicknessProperty.AddOwner(typeof(CappedLine));
public double StrokeThickness
{
get { return (double)GetValue(StrokeThicknessProperty); }
set { SetValue(StrokeThicknessProperty, value); }
}
public static DependencyProperty CapStrokeProperty =
DependencyProperty.Register(
"CapStroke",
typeof(Brush),
typeof(CappedLine));
public Brush CapStroke
{
get { return (Brush)GetValue(CapStrokeProperty); }
set { SetValue(CapStrokeProperty, value); }
}
public static readonly DependencyProperty CapStrokeThicknessProperty =
DependencyProperty.Register(
"CapStrokeThickness",
typeof(double),
typeof(CappedLine));
public double CapStrokeThickness
{
get { return (double)GetValue(CapStrokeThicknessProperty); }
set { SetValue(StrokeThicknessProperty, value); }
}
public static readonly DependencyProperty LinePathProperty =
DependencyProperty.Register("LinePath", typeof(PathGeometry), typeof(CappedLine),
new FrameworkPropertyMetadata(
null,
FrameworkPropertyMetadataOptions.AffectsRender, // choose appropriate flags here!!!
LinePathChangedCallback));
static void LinePathChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
CappedLine me = sender as CappedLine;
if (null != me)
{
me.OnLinePathChanged((PathGeometry)args.NewValue);
}
}
public PathGeometry LinePath
{
get { return (PathGeometry)GetValue(LinePathProperty); }
set { SetValue(LinePathProperty, value); }
}
public virtual void OnLinePathChanged(PathGeometry value)
{
}
public static readonly DependencyProperty BeginCapProperty =
DependencyProperty.Register("BeginCap", typeof(Geometry), typeof(CappedLine),
new FrameworkPropertyMetadata(
null,
FrameworkPropertyMetadataOptions.AffectsRender, // choose appropriate flags here!!!
BeginCapChangedCallback));
static void BeginCapChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
CappedLine me = sender as CappedLine;
if (null != me)
{
me.OnBeginCapChanged((Geometry)args.NewValue);
}
}
public Geometry BeginCap
{
get { return (Geometry)GetValue(BeginCapProperty); }
set { SetValue(BeginCapProperty, value); }
}
public virtual void OnBeginCapChanged(Geometry value)
{
}
public static readonly DependencyProperty EndCapProperty =
DependencyProperty.Register("EndCap", typeof(Geometry), typeof(CappedLine),
new FrameworkPropertyMetadata(
null,
FrameworkPropertyMetadataOptions.AffectsRender, // choose appropriate flags here!!!
EndCapChangedCallback));
static void EndCapChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
CappedLine me = sender as CappedLine;
if (null != me)
{
me.OnEndCapChanged((Geometry)args.NewValue);
}
}
public Geometry EndCap
{
get { return (Geometry)GetValue(EndCapProperty); }
set { SetValue(EndCapProperty, value); }
}
public virtual void OnEndCapChanged(Geometry value)
{
}
}
}
然后使用它:
<Window x:Class="LineCaps.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:loc="clr-namespace:LineCaps"
Title="MainWindow">
<Viewbox>
<Canvas Height="350" Width="525">
<loc:CappedLine BeginCap="M0,0 L6,-6 L6,6 z" EndCap="M0,-3 L0,3 L6,3 L6,-3 z" Stroke="Gold" StrokeThickness="1" CapStroke="Green" CapStrokeThickness="1" Canvas.Left="40" Canvas.Top="60">
<loc:CappedLine.LinePath>
<PathGeometry Figures="M0,0 L120,120" />
</loc:CappedLine.LinePath>
</loc:CappedLine>
<loc:CappedLine EndCap="M0,0 L6,-6 L6,6 z" Stroke="Blue" StrokeThickness="1" CapStroke="Red" CapStrokeThickness="1" Canvas.Left="40" Canvas.Top="200" RenderTransformOrigin="1.5,0.5">
<loc:CappedLine.BeginCap>
<EllipseGeometry Center="0,0" RadiusX="6" RadiusY="6" />
</loc:CappedLine.BeginCap>
<loc:CappedLine.LinePath>
<PathGeometry Figures="M0,0 C1,1 10.5,75.5 48.5,66.5 86.5,57.5 53.5,3.5000146 105.5,16.500091 157.5,29.500166 164.5,87.500505 164.5,87.500505" />
</loc:CappedLine.LinePath>
<loc:CappedLine.RenderTransform>
<RotateTransform Angle="0" />
</loc:CappedLine.RenderTransform>
</loc:CappedLine>
</Canvas>
</Viewbox>
</Window>