1

我目前需要创建一个渡轮系统的可视化表示,以显示实际渡轮在海上的位置和货物的状态。渡轮包含卡车,卡车包含汽车。我需要在甲板上显示实际的卡车及其 xy 位置。当渡轮装载时,卡车的位置会经常更新,因此看起来很生动。我还需要在卡车上展示实际的汽车。卡车、汽车和渡轮也有一些需要显示的状态。所以我有一个层次结构的数据,我需要以一种相当现实的方式进行可视化。

在 WPF 中实现这种东西的好方法是什么?我是否应该将 MVVM 与一个 TreeView 控件一起使用,并为海运、渡轮、卡车和汽车创建一个 HierarchicalDataTemplates,并为 TreeView 创建一个 ControlTemplate?或者我应该更好地使用 UserControls 并在代码中编写和更新它们,而不是数据绑定到 ViewModel 的可观察集合。你有这方面的经验吗?你会怎么做?你能勾勒出类/控制设置吗?

4

4 回答 4

4

我建议制作一个“无外观”的控件,而不是制作用户控件。通常,我将用户控件用作我的无外观控件的胶水/容器。无外观控件的一个示例是 Button 类。它包含一个默认样式,在 Blend 中,您可以随意修改样式。它还支持可视状态管理器,因此您可以在状态更改时更改演示文稿的外观。您可以将无外观控件的代码隐藏视为迷你 ViewModel。在这里可以混合一些演示文稿和您的域类。

如果您遵循相同的设计,您可以创建一个 Ferry 无外观控件。这个控件会有一组它自己的依赖属性(可能监听 DP 的 OnChange)。

您的 Ferry 控件可能有一个名为“Trucks”的 ObservableCollection DP。

然后在您的 Themes\generic.xaml 中,为您的 Ferry 控件创建一个默认样式。您的默认样式可能具有 ItemsControl 和 ItemsSource={TemplateBinding Trucks}。ItemsControl 面板模板,可以是您自己的用于安排卡车的自定义面板,或者您可以使用 Canvas。对于 ItemsControl 项目模板,您将拥有如下内容:

<DataTemplate>
     <mynamespace:TruckControl/>
</DataTemplate>

你的 Truck 控件,也将是一个具有自己默认样式的无外观控件,并且它的数据上下文已经设置,因此您可以直接执行 {Binding Path=xyz}。您的 Truck 控件还可以将其设置为 Canvas.Left/Top(如果您选择在 pervious items 控件中使用画布..或者如果您为其制作了自定义面板,它可能根本不设置其位置)或渲染变换为把它放在正确的 X,Y 上。您还可以使用卡车模板中的项目控件以与在渡轮控件中渲染卡车相同的方式渲染汽车。还可以为 VisualStateManager 创建状态以使其完全可支持 Blend。因此,例如,如果卡车进入“问题状态”,您可以轻松地将该状态设置为混合样式,使其闪烁红色。

我知道这听起来需要消化很多东西,但最终拥有所有支持 MVVM 模型的可样式化控件将使您的生活轻松 1000000 倍。

我建议研究 Microsoft 的 silverlight 工具包,以了解如何进行无外观控件等。尝试查看一个简单的控件,例如 DatePicker ( http://silverlight.codeplex.com/SourceControl/changeset/view/25992# ) 一个警告是忽略 DatePicker.xaml 文件(它只是通用内容的镜像。 xaml 并且如果您只是删除它就不会发生任何不好的事情)。

您应该密切注意的事项是:

1.) 类的属性。这些帮助 Blend 知道如何处理你的控制。

2.) OnApplyTemplate 覆盖。您可以在此处从模板中提取特定元素。这些被称为“部件”,您将在 Blend 中看到部件选项卡。#1 中的属性可以定义模板中的“部分”是什么以及它们应该是什么类型。

3.) 构造函数中的 DefaultStyleKey = typeof(...)。这告诉 Silverlight 在 generic.xaml 中使用什么默认模板

4.) 查看 Themes\generic.xaml。这是一个特殊的硬编码文件位置,用于存储所有默认模板。搜索 DatePicker 样式,您会明白的:)

祝你好运!

于 2009-08-24T06:32:46.200 回答
2

我只是想让你知道,我是如何实现它的。事实证明,根本没有必要为此编写自定义控件或 UserControls。我所做的只是为汽车、轮船、渡轮、卡车等 ViewModel 编写数据模板。例如,FerryViewModel 的数据模板包含一个带有 Canvas 类型的 ItemsPanel(以便能够定位卡车)的 ItemsControl 和一个作为 TruckViewModel 的 DataTemplate 的 ItemTemplate。一个非常简单和快速的方法。

于 2009-09-05T18:57:11.817 回答
1

我建议让一个用户控件处理所有绘图。否则,您可能会迷失对象的层次结构。此外,如果添加其他项目,例如汽车、卡车和渡轮上的人,它也会变得更容易。

如果您的模型是分层的,那么您只需将顶层传递到控件中,然后让控件自行排序。

MVVM 适用于现有控件,但现有 WPF 控件仅在有一个接近您需要的控件时才有效,并且只需进行一些调整即可。我想不出 WPF 中的标准控件与您所需要的很接近,所以是时候编写一个新控件了。

于 2009-08-23T04:32:40.117 回答
0

WPF 非常适合视图模型。如果您可以在特别需要之前保留代码,那么您可以更轻松地将 ui 与数据分开。如果数据模型在不同的显示之间没有变化,它将允许您的用户界面更具可升级性。

于 2009-08-22T10:52:35.577 回答