WPF折线相对点值和拉伸用于绘制图形

时间:2009-11-10 18:01:33

标签: wpf fill stretch polyline

我正在尝试创建一个非常简单的图形组件,该组件由表示图形线的同一网格单元格中的一系列折线组成。我的策略是查看我的集合中的所有点,确定最小值和最大值,然后相应地计算0到1之间的数字,并使用Stretch =“Fill”拉伸每条折线以填充网格单元格。我期望的效果是0,.5处的点将垂直位于单元格的中心,但实际上,折线被垂直拉伸以填充整个单元格,具体取决于最小和最大Y值。例如。如果.5是我的最大值,而.7是我在Polyline中的最小值,则.5将在单元格的顶部清晰,.7清除在底部,而不是.5在中心和.7 7/10到底部。

这是一个简单的例子,其中包含两条折线和0到1之间的计算点。您会注意到红色折线直接位于蓝色折线之上,即使红色Y值更大。红色折线应看起来与蓝色相同,但在细胞中的方向略低。然而,它被拉伸以填充整个单元格,因此它直接位于蓝色顶部。

<Window x:Class="Test.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="100" Width="300">
<Grid>
    <Polyline
        Stretch="Fill"
        Stroke="Blue"
        Points="0,0 0.2,0 0.2,0.363636363636364 0.4,0.363636363636364 0.4,0.636363636363636 0.6,0.636363636363636 0.6,0.0909090909090909 0.8,0.0909090909090909 0.8,0 1,0" />
    <Polyline
        Stretch="Fill"
        Stroke="Red"
        Points="0,0.363636363636364 0.2,0.363636363636364 0.2,0.727272727272727 0.4,0.727272727272727 0.4,1 0.6,1 0.6,0.454545454545455 0.8,0.454545454545455 0.8,0.363636363636364 1,0.363636363636364" />
</Grid>

我使用0到1值的原因是因为我希望网格单元的宽度和高度可以很容易地改变,例如通过滑块或其他东西来调整图形的高度,或者将窗口拖得更宽以调整宽度。所以我尝试使用这种拉伸策略来实现这一目标,而不是计算出拉伸的像素值。

有关如何实现这一目标的任何建议吗?

感谢。

2 个答案:

答案 0 :(得分:3)

我有类似的问题,因为我找不到一种简单的方法来缩放多个形状。最后使用内置多个DrawingGroup的{​​{1}}结束。所以他们一起扩展。以下是使用此方法的图表。看起来笨重,但应该快速工作。另外,您最有可能从代码填充线段:

GeometryDrawing

如果您不需要图表始终在0和1之间缩放,则可以先删除<Window x:Class="Polyline.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="100" Width="300"> <Grid> <Image> <Image.Source> <DrawingImage> <DrawingImage.Drawing> <DrawingGroup> <GeometryDrawing Brush="Transparent"> <GeometryDrawing.Geometry> <RectangleGeometry Rect="0,0,1,1"> <RectangleGeometry.Transform> <ScaleTransform ScaleX="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType=Grid}}" ScaleY="{Binding ActualHeight, RelativeSource={RelativeSource AncestorType=Grid}}"/> </RectangleGeometry.Transform> </RectangleGeometry> </GeometryDrawing.Geometry> </GeometryDrawing> <GeometryDrawing> <GeometryDrawing.Pen> <Pen Brush="Blue" Thickness="1"/> </GeometryDrawing.Pen> <GeometryDrawing.Geometry> <PathGeometry> <PathGeometry.Transform> <ScaleTransform ScaleX="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType=Grid}}" ScaleY="{Binding ActualHeight, RelativeSource={RelativeSource AncestorType=Grid}}"/> </PathGeometry.Transform> <PathGeometry.Figures> <PathFigure StartPoint="0,0"> <PathFigure.Segments> <LineSegment Point="0.2,0"/> <LineSegment Point="0.2,0.363636363636364"/> <LineSegment Point="0.4,0.363636363636364"/> <LineSegment Point="0.4,0.636363636363636"/> <LineSegment Point="0.6,0.636363636363636"/> <LineSegment Point="0.6,0.0909090909090909"/> <LineSegment Point="0.8,0.0909090909090909"/> <LineSegment Point="0.8,0"/> <LineSegment Point="1,0"/> </PathFigure.Segments> </PathFigure> </PathGeometry.Figures> </PathGeometry> </GeometryDrawing.Geometry> </GeometryDrawing> <GeometryDrawing> <GeometryDrawing.Pen> <Pen Brush="Red" Thickness="1"/> </GeometryDrawing.Pen> <GeometryDrawing.Geometry> <PathGeometry> <PathGeometry.Transform> <ScaleTransform ScaleX="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType=Grid}}" ScaleY="{Binding ActualHeight, RelativeSource={RelativeSource AncestorType=Grid}}"/> </PathGeometry.Transform> <PathGeometry.Figures> <PathFigure StartPoint="0,0.363636363636364"> <PathFigure.Segments> <LineSegment Point="0.2,0.363636363636364"/> <LineSegment Point="0.2,0.727272727272727"/> <LineSegment Point="0.4,0.727272727272727"/> <LineSegment Point="0.4,1"/> <LineSegment Point="0.6,1"/> <LineSegment Point="0.6,0.454545454545455"/> <LineSegment Point="0.8,0.454545454545455"/> <LineSegment Point="0.8,0.363636363636364"/> <LineSegment Point="1,0.363636363636364"/> </PathFigure.Segments> </PathFigure> </PathGeometry.Figures> </PathGeometry> </GeometryDrawing.Geometry> </GeometryDrawing> </DrawingGroup> </DrawingImage.Drawing> </DrawingImage> </Image.Source> </Image> </Grid> </Window>

答案 1 :(得分:3)

我曾经遇到过这个问题。当时我发现解决方案repka提出但不满意,因为它相对复杂,并没有我想要的效率。

我通过编写一组简单的 Viewbox形状类解决了这个问题,它与内置PathLinePolyline和{的工作方式完全相同{1}}除了它们之外,它们可以让您轻松地按照自己的方式工作。

我的课程是PolygonViewboxPathViewboxLineViewboxPolyline,它们的用法如下:

ViewboxPolygon

如您所见,我的 Viewbox形状类与普通形状(<edf:ViewboxPolyline Viewbox="0 0 1 1" <!-- Actually the default, can be omitted --> Stretch="Fill" <!-- Also default, can be omitted --> Stroke="Blue" Points="0,0 0.2,0 0.2,0.3 0.4,0.3" /> <edf:ViewboxPolygon Viewbox="0 0 10 10" Stroke="Blue" Points="5,0 10,5 5,10 0,5" /> <edf:ViewboxPath Viewbox="0 0 10 10" Stroke="Blue" Data="M10,5 L4,4 L5,10" /> PolylinePolygonPath一样使用除了额外的Line参数,以及它们默认为Viewbox的事实。 Viewbox参数在用于指定形状的坐标系中指定应使用Stretch="Fill"FillUniform设置拉伸的几何体区域,而不是使用{{1 }}

这样可以非常精确地控制拉伸,并且可以很容易地使单独的形状彼此精确对齐。

以下是 Viewbox形状类的实际代码,包括包含常用功能的抽象基类UniformToFill

Geometry.GetBounds

享受!