WPF中的数据绑定形状和线条

时间:2013-01-11 01:49:33

标签: wpf data-binding path geometry shapes

我正在开发一个需要能够在WPF中操作形状和线条的应用程序。我最初的想法是将一个集合数据绑定到ListBox并在datatemplate中使用Rectangles,将每个填充属性设置为图像。除圆形和几个矩形外,这对大多数形状都有效。由于重新调整图像大小会导致像素化并且线条会改变大小,因此结果不如恒星。

我花了一些时间浏览SO和其他一些关于Path元素的网站,但没有发现任何真正符合我需求的网站。我的猜测是我需要为每种类型的形状生成不同的路径,并使用类似于Path drawing and data binding的转换器或使用http://www.telerik.com/help/wpf/raddiagram-overview.html或类似的rad工具对它们进行数据绑定。

我的问题:是否有更简单的方法来完成此示例或任何其他示例?

编辑:我还需要能够添加文字。不知道我怎么能用路径做到这一点......也许是一个ContentControl?

1 个答案:

答案 0 :(得分:2)

您可以通过将Path.Data数据绑定到Geometry来绘制各种形状。您可以从点列表中生成Geometry。转换器非常适合这种适应。

例如,我通过将Path.Data属性数据绑定到StreamGeometry来绘制螺旋,我生成了一个由视图模型管理的点列表,它可以很好地满足我的需求:< / p>

// ViewModel ...
public class ViewModel 
{
    [Notify]
    public IList<Point> Points { get; set; }
}

// Converter ... 
public class GeometryConverter : IValueConverter
{
    public Object Convert(Object value, Type targetType, Object parameter, CultureInfo culture)
    {
        if (value == null || value == DependencyProperty.UnsetValue)
        {
            return value;
        }

        var points = (IList<Point>)value;            
        var i = 0; 
        var newPath = new StreamGeometry();

        using (var context = newPath.Open())
        {
            var begun = false;

            for (var i = 0; i < points.Count; i++)
            {
                var current = points[i];

                if (!begun)
                {
                    begun = true;
                    context.BeginFigure(current, true, false);
                }
                else
                {
                    context.ArcTo(current, new Size(radius, radius), angle, false, SweepDirection.Counterclockwise, true, true);
                }
            }
        }

        newPath.Freeze();
        return newPath.GetFlattenedPathGeometry();
    }
}

XAML:

<Canvas>
    <Path StrokeThickness="{Binding StrokeWidth}"
          Canvas.Top="{Binding Top}"
          Canvas.Left="{Binding Left}"
          Data="{Binding Points, Converter={StaticResource GeometryConverter}}">
        <Path.Stroke>
            <SolidColorBrush Color="{Binding CurrentColor}" />
        </Path.Stroke>
    </Path>
</Canvas>

至于文本,绑定TextBlock元素并根据需要在'Canvas`上排列它们不是更好吗?