我需要根据提供的大小创建多个形状(所有形状都具有相同的高度/宽度),并且将它们的大小数据绑定到datacontext上提供的属性。
大多数形状都很简单:圆形(高度/宽度限定的椭圆),方形(高度/宽度限制的矩形),菱形(与方形相同,然后使用RotateTransform),+(两条线),X(两行)。
但是我想弄清楚如何为三角形做这件事,我无法弄明白。它需要是一个填充的对象,所以我不能只用三行来做。
但我所见过的所有方式(包括Path
或Polygon
)最终会获取Point
个对象(StartPoint
,{{ 1}}等。而且您无法绑定EndPoint
对象的X
或Y
值。
我错过了什么吗?或者我是否需要编写自己的自定义形状?
编辑:为了增加一点点清晰度...我正在创建的三角形类型并不重要。它可以是等边或等腰。我的目标是等腰,因此它将具有数据绑定宽度的基础,并且三角形的顶部“尖端”将位于数据绑定宽度的中点并且在Y = 0处。这只是为了简单起见而进行的优化
答案 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>