2009-09-10 90 views
2

仍然通过学习XAML/WPF选择我的方式。如果有人能告诉我如何完成以下任务 - 这对帮助我开发我的下一个项目(以及几个类似的项目)将有很大的帮助。WPF类似CAD的系统 - 类中的所有数据

说我有一个对象的集合,它定义了要在画布上绘制的对象。这些对象包含渲染对象所需的所有信息,包括形状,颜色和位置。是否可以创建绑定到该集合并处理渲染的XAML控件,还是通过在代码隐藏中在画布上绘图来更好地完成此操作?

另一点 - 对象最终必须是可点击选择的,可通过矩形套索选择,并且可拖动。这不必在某人提供的示例代码中解决,但我认为可能与此相关,因为它可能会影响各种实现。

下面的示例类。提前致谢。

Class DrawingElement 

    readonly property Shape as string ("circle", "square", "triangle") 
    readonly property Position as point (coordinates) 
    readonly property Color as string ("red", "blue", "yellow") 

end class 

Sub Main 

    dim lst as new List(of DrawingElement) 

    lst.add(new DrawingElement("Circle", 10,20, "Blue")) 
    lst.add(new DrawingElement("Square", 80,35, "Red")) 
    lst.add(new DrawingElement("Triangle", 210,120, "Yellow")) 

    <draw lst!> 

End Sub 

回答

2

可以这样做,但不能使用魔术字符串(例如,“circle”),就像你的例子。

首先,您应该基于现有的框架元素设计您的models,而不是设计模型以创建一些新的UI元素或挣扎于create code that interprets between them

WPF已经有一个椭圆(圆),矩形(正方形)和其他几何图元的主机供您使用。您需要创建包含公共可绑定属性的模型,您可以将这些属性绑定到这些元素的实例以控制其形状和位置。

没有进入太多细节(或测试),我会做这样的事情

public class GeometricElement : INotifyPropertyChanged 
{ 
    // these are simplified and don't show INPC code 
    public double Left {get;set;} 
    public double Top {get;set;} 
    public Brush Fill {get;set;} 
    // ... 
} 

// ... 

public class Square : GeometricElement 
{ 
    public double Width {get;set;} 
    public double Height {get;set;} 
} 

// ... 

// bound to the window 
public class CadAppDataContext 
{ 
    public ObservableCollection<GeometricElement> Elements {get; private set;} 
} 

而且在我的XAML中,它看起来像

<ItemsControl ItemsSource="{Binding Source={StaticResource cadAppDataContext}}" > 
    <ItemsControl.ItemsPanel> 
    <ItemsPanelTemplate> 
     <Canvas /> 
    </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.Resources> 
    <DataTemplate TargetType="{x:Type me:Square}"> 
     <Rectangle 
     Canvas.Left="{Binding Left}" 
     Canvas.Top="{Binding Top}" 
     Width="{Binding Width}" 
     Height="{Binding Height}" 
     Fill="{Binding Fill}" /> 
    </DataTemplate> 
    <!-- more DataTemplates for circle, triangle, etc etc --> 
    </ItemsControl.Resources> 
</ItemsControl> 

ItemsControl的将创建一个Canvas元素,并且对于我的Elements集合中的每个GeometricElement,它将根据Elements中的对象类型添加一个新的子UI元素。

项目控件绑定到集合,并且可以根据代码中集合中发生的事情添加或删除元素。它通过查找为特定类型设计的DataTemplate来确定要添加的UI元素。这是一种常见而且重要的模式,因此从长远来看,使用魔术弦会伤害到你;神奇的字符串路线不会让您利用已经内置于WPF的框架的力量。

现在,我不是说这可以开箱即用。你可能会遇到不会受到一些沉重负担而无法绑定的属性。您甚至可能需要扩展几何图元以使其表现得您想要的。但是这是WPF应用程序中使用的模式。理解模式并使用它将有助于避免数小时的压力和失败。

+0

对不起,我不会说VBineese。但代码很简单,我相信你可以解释我的咕噜声和吱吱声。 – Will 2009-09-10 13:01:10

+0

真正的数据上没有“circle”或“rectangle”值的字符串属性 - 我只是为了清晰起见而使用了这样的示例。在真实数据中,集合中的不同元素是根据它们的不同形状绘制的(现实世界的例子:试图在地图上绘制像公园,医院和加油站这样的位置,集合将包含所有的位置,每种类型都会使用不同的图标)。 – taglius 2009-09-10 13:04:06

+0

我完成了我的编辑,这应该阐明WPF如何使用基于类型的DataTemplates来呈现内容。这是关键。理解它并利用它可以节省大量的代码和汗水。 – Will 2009-09-10 13:09:33