我应该在WPF中使用哪个容器来绘制具有正确定位的几何形状?

时间:2014-03-13 13:33:53

标签: wpf layout shapes

我想在WPF中使用Shapes以类似于几何图表或绘图的方式显示一些数学定义的对象(点,折线,参考轴)。我想使用Shapes因为它们的交互性,因为用户应该点击它们,用鼠标悬停突出显示它们等。

Shape对象本身应在ViewModel中数据绑定到它们的几何定义。我可以根据最方便的选择(PointCollection,PathFigure,Point等)来选择每个属性的类型。

问题是:到目前为止,我正在尝试使用Canvas容器,它具有一些特殊的布局特征,这使我很难做到正确。具体来说,它的起源位于左上角,所以我的形状显得颠倒,除非我使用RenderTransform(我不反对);

除此之外,我在ViewModel(类型为Rect)中有一个BoundingBox属性,它应该用于控件内的“fit”或“autozoom”,但由于模型坐标不是屏幕坐标,我会有应用一些变换。

不幸的是,我只能将变换应用于Geometries,我可以使用带有DrawingImage的Image作为源,使用描述形状的GeometryDrawings。但是,我首先失去了形状所需的所有特征(主要是造型和交互)。

这就是我陷入困境的原因,所以我的问题归结为:

“我如何转换形状的几何体,使它们正确定位在画布中的'参考视口'内?”

这是一些令人不满意的代码,Image控件显示所需的布局:

enter image description here

XAML:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:DrawingGraficos"
    x:Class="DrawingGraficos.MainWindow"
    x:Name="Window"
    Title="MainWindow"
    Width="204.333" Height="181">

    <Window.DataContext>
        <local:DesenhoViewModel/>
    </Window.DataContext>

    <Window.Resources>
        <local:TranslacaoConverter x:Key="TranslacaoConverter"/>
    </Window.Resources>

    <UniformGrid Rows="0" Columns="2">
        <Canvas x:Name="canvasviewport">
            <Polygon Points="{Binding BoundingBoxCorners}" Fill="LightGray"/>
            <Path Stroke="Red" StrokeThickness="2" Data="{Binding GeometriaLinhaSimetria}"/>
        </Canvas>
        <Image>
            <Image.LayoutTransform>
                <ScaleTransform ScaleY="-1" CenterY=".5"/>
            </Image.LayoutTransform>
            <Image.Source>
                <DrawingImage>
                    <DrawingImage.Drawing>
                        <DrawingGroup>
                            <DrawingGroup.ClipGeometry>
                                <RectangleGeometry Rect="{Binding Limites}"/>
                            </DrawingGroup.ClipGeometry>
                            <GeometryDrawing Brush="LightGray">
                                <GeometryDrawing.Geometry>
                                    <RectangleGeometry Rect="{Binding Limites}"/>
                                </GeometryDrawing.Geometry>
                            </GeometryDrawing>
                            <GeometryDrawing Geometry="{Binding GeometriaLinhaSimetria}">
                                <GeometryDrawing.Pen>
                                    <Pen Brush="Red" Thickness="2"/>
                                </GeometryDrawing.Pen>
                            </GeometryDrawing>
                        </DrawingGroup>
                    </DrawingImage.Drawing>
                </DrawingImage>
            </Image.Source>
        </Image>
    </UniformGrid>

</Window>

视图模型:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Miotec.MVVM;
using System.Windows;
using System.Windows.Media;

namespace DrawingGraficos
{
    public class DesenhoViewModel : ViewModelBase {

        public Rect Limites {
            get {
                double largura = 70;
                double altura = 100;
                return new Rect(new Point(-largura*0.5,-30), new Point(largura*0.5,altura-30));
            }
        }

        public PointCollection BoundingBoxCorners {
            get {
                return new PointCollection() {
                    Limites.BottomLeft, Limites.TopLeft, Limites.TopRight, Limites.BottomRight
                };
            }
        }

        public Point Origem { get { return new Point(0,0); } }

        public List<Point> LinhaSimetria {
            get {
                return new List<Point> {
                    new Point(-3,-20),
                    new Point(0,-15),
                    new Point(2,-10),
                    new Point(4,-5),
                    new Point(4,0),
                    new Point(2,5),
                    new Point(2,10),
                    new Point(0,15),
                    new Point(-2,20),
                    new Point(-2,25),
                    new Point(-2,30),
                    new Point(-2,35)
                };
            }
        }

        public Geometry GeometriaLinhaSimetria {
            get {
                var sb = new StringBuilder("M");
                foreach (var p in LinhaSimetria) {
                    sb.AppendFormat(" {0};{1}", p.X, p.Y);
                }
                string result = sb.ToString().Replace(",",".").Replace(";",",");
                return Geometry.Parse(result);
            }
        }

    }
}

0 个答案:

没有答案