我有一系列与形状相关的视图模型类。典型的传统层次结构:基本ShapeVm类,然后是LineVm,CircleVm等。每个类都公开适当类型的Geometry属性。
public abstract class ShapeVm
{
public abstract Geometry Geometry { get; }
}
public class LineVm : ShapeVm
{
public override Geometry Geometry => new LineGeometry(P1, P2);
public Point P1 { get; set; }
public Point P2 { get; set; }
}
直到现在,无论形状类型如何,我都使用相同的路径Path在XAML中公开它们。
<Path Fill="Yellow" StrokeThickness="3" Data={Binding Geometry}"/>
但是现在我希望能够将转换应用于XAML中的每个PathGeometry。这给我带来了“制造我的代码气味”的问题:
我的方法是在XAML中手动构造我的Path对象的PathGeometry并设置其Transform属性。但是我无法弄清楚如何轻松地将所有各种几何类型(LineGeometry,EllipseGeometry等)轻松转换为PathGeometry。我需要为PathGeometry提供一个“ Figures”属性。
<Path Fill="Yellow" Stroke="Blue" StrokeThickness="3">
<Path.Data>
<PathGeometry Figures="???" **** WHAT DO I USE HERE??? ***
Transform="{Binding MyViewGeoTransform}"/>
</Path.Data>
</Path>
PathGeometry.Figures属性的类型为PathFigureCollection。是否有内置转换器将任何旧的WPF Geometry转换为PathFigureCollection? System.Windows.Media.GeometryConverter似乎无法解决问题。
是否有一些明显的简单方法来实现此目的,而我却不这样做了?我应该只写转换器吗?
(我意识到我可以为每种形状类型编写不同的数据模板,并且如果它最干净,可以这样做,但是在XAML中仅使用一个Path对象会吸引我的简单性)
答案 0 :(得分:1)
将“变换”应用于路径的最简单方法可能是设置其RenderTransform
属性:
<Path Fill="Yellow" StrokeThickness="3"
Data="{Binding Geometry}"
RenderTransformOrigin="0.5,0.5"
RenderTransform="{Binding MyViewGeoTransform}"/>
如果出于某些原因而不希望这样做,则可以将MultiBinding与创建转换后的GeometryGroup的转换器一起使用:
<Path Fill="Yellow" StrokeThickness="3">
<Path.Data>
<MultiBinding Converter="{StaticResource TransformedGeometryConverter}">
<Binding Path="Geometry"/>
<Binding Path="MyViewGeoTransform"/>
</MultiBinding>
</Path.Data>
</Path>
转换器:
public class TransformedGeometryConverter : IMultiValueConverter
{
public object Convert(
object[] values, Type targetType, object parameter, CultureInfo culture)
{
var geometry = new GeometryGroup { Transform = (Transform)values[1] };
geometry.Children.Add((Geometry)values[0]);
return geometry;
}
public object[] ConvertBack(
object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}