数据库三角形创作?

时间:2011-11-08 18:46:43

标签: wpf data-binding shapes

我需要根据提供的大小创建多个形状(所有形状都具有相同的高度/宽度),并且将它们的大小数据绑定到datacontext上提供的属性。

大多数形状都很简单:圆形(高度/宽度限定的椭圆),方形(高度/宽度限制的矩形),菱形(与方形相同,然后使用RotateTransform),+(两条线),X(两行)。

但是我想弄清楚如何为三角形做这件事,我无法弄明白。它需要是一个填充的对象,所以我不能只用三行来做。

但我所见过的所有方式(包括PathPolygon)最终会获取Point个对象(StartPoint,{{ 1}}等。而且您无法绑定EndPoint对象的XY值。

我错过了什么吗?或者我是否需要编写自己的自定义形状?

编辑:为了增加一点点清晰度...我正在创建的三角形类型并不重要。它可以是等边或等腰。我的目标是等腰,因此它将具有数据绑定宽度的基础,并且三角形的顶部“尖端”将位于数据绑定宽度的中点并且在Y = 0处。这只是为了简单起见而进行的优化

2 个答案:

答案 0 :(得分:2)

绑定到积分是最佳/唯一的方式。 Point的X和X属性无法绑定,因为它们不会引发PropertyChanged事件。 Point是一个结构,结构应该是只读的。

PointCollection类引发了正确的事件,因此您可以绑定它。这允许您通过替换点来修改点集合来操纵三角形。不要改变点,但要更换它们,以便引发适当的事件。

答案 1 :(得分:2)

行为类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Shapes;
using System.Windows.Media;

namespace WpfApplication1
{
    public enum ShapeType
    {
        Rectangle,
        Isosceles,
        Ellipse,
        Dice,
        Hexagon
    }

    public class PathControl
    {
        public static readonly DependencyProperty ShapeTypeProperty =
            DependencyProperty.RegisterAttached("ShapeType",
            typeof(ShapeType?),
            typeof(DependencyObject),
            new PropertyMetadata(null, 
                new PropertyChangedCallback((sender, args) => 
                { 
                    Path path = sender as Path;
                    ShapeType? shapeType = (ShapeType?)args.NewValue;

                    //todo: use a WeakEvent
                    path.SizeChanged += 
                        (pathSender, pathArgs) => 
                        {
                            PathControl.InvalidatePath((Path)sender, shapeType);
                        };

                })));


        private static void InvalidatePath(Path path, ShapeType? shapeType)
        {
            if (path != null
                && shapeType.HasValue)
            {
                string source = null;

                double netWidth = path.Width - 2 * path.StrokeThickness,
                       netHeight = path.Height - 2 * path.StrokeThickness;

                if (shapeType == ShapeType.Rectangle)
                {
                    source = string.Format("M0,0 h{0} v{1} h-{0} z",
                        new object[2]
                        {
                            netWidth,
                            netHeight
                        });
                }
                else if (shapeType == ShapeType.Isosceles)
                {
                    source = string.Format("M0,{1} l{0},-{1} {0},{1} z",
                        new object[2]
                        {
                            netWidth / 2,
                            netHeight
                        });
                }
                else
                {
                    throw new NotImplementedException(shapeType.ToString());
                }

                path.Data = Geometry.Parse(source);
            }
        }

        public static void SetShapeType(DependencyObject o, ShapeType e)
        {
            o.SetValue(PathControl.ShapeTypeProperty, e);
        }

        public static ShapeType? GetShapeType(DependencyObject o)
        {
            return (ShapeType)o.GetValue(PathControl.ShapeTypeProperty);
        }
    }
}

XAML:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        xmlns:local="clr-namespace:WpfApplication1">
    <Grid>
        <Path Width="100" Height="100" Stroke="Green" StrokeThickness="2" Fill="Yellow"
              local:PathControl.ShapeType="Isosceles">
            <Path.RenderTransform>
                <RotateTransform Angle="90"></RotateTransform>
            </Path.RenderTransform>
        </Path>
    </Grid>
</Window>