我目前需要创建一个渡轮系统的直观表示,显示实际渡轮在海上的位置和货物状态。渡轮包含卡车,卡车包含汽车。我需要在甲板上显示实际卡车及其xy位置。当渡轮装载时,卡车的位置经常更新,因此看起来很动画。我还需要在卡车上显示实际的车辆。卡车,汽车和渡轮也有一些需要显示的状态。所以我有一个数据的层次结构,我需要以一种相当现实的方式进行可视化。
在WPF中实现这种东西的好方法是什么?我应该将MVVM与一个TreeView控件一起使用,并为SeaView,渡轮,卡车和汽车创建HierarchicalDataTemplates,为TreeView创建ControlTemplate吗?或者我应该更好地使用UserControls并在代码中编写和更新它们,而不是数据绑定到ViewModel的可观察集合。你有这方面的经验吗?你会怎么做?你能勾勒出班级/控制设置吗?
答案 0 :(得分:4)
我建议制作一个“无视”控件,而不是制作用户控件。通常我将用户控件用作胶水/容器,用于我的无形控件。一个无外观控件的例子是Button类。它包含默认样式,在Blend中,您可以随意修改样式。它还支持可视状态管理器,因此您可以更改状态更改时表示的外观。您可以将无视控件的代码隐藏视为迷你ViewModel。在这里 ok 混合了一些演示文稿内容和你的域类。
如果您遵循相同的设计,您可以创建一个Ferry无表情控件。该控件将具有一组自己的依赖属性(可能监听DP的OnChange)。
您的Ferry控件可能有一个名为“Trucks”的ObservableCollection DP。
然后在您的Themes \ generic.xaml中,为您的Ferry控件创建默认样式。您的默认样式可能有ItemsControl,其ItemsSource = {TemplateBinding Trucks}。 ItemsControl面板模板可以是您自己的用于排列卡车的自定义面板,也可能是您使用Canvas。对于ItemsControl项目模板,您将具有以下内容:
<DataTemplate>
<mynamespace:TruckControl/>
</DataTemplate>
您的卡车控制,也是一个具有自己默认样式的无形控件,并且它的数据上下文已经设置好,因此您可以直接执行{Binding Path = xyz}。你的卡车控制也可以设置它的Canvas.Left / Top(如果你选择在前面的项目控件中使用画布......或者如果你为它制作一个自定义面板它可能根本没有设置它的位置)或渲染转换为将其置于正确的X,Y。您还可以使用卡车模板中的物品控制来以与您在渡轮控制中的卡车相同的方式渲染汽车。还可以为VisualStateManager创建状态,使其完全支持Blend。因此,如果卡车进入“问题状态”,您可以轻松地将该状态设置为混合,以使其闪烁红色,例如。
我知道消化听起来很多,但最终有可控制的控件,所有支持MVVM模型都会让你的生活更轻松。
我建议学习微软的Silverlight工具包,以便更好地了解如何进行无形控制等。尝试查看一个简单的控件,比如DatePicker(http://silverlight.codeplex.com/SourceControl/changeset/view/25992#)。一个警告是忽略DatePicker.xaml文件(它只是在generic.xaml中放入的内容的镜像,如果你刚删除它就不会发生任何不好的事情)。
你应该密切注意的事项是:
1。)类的属性。这些帮助Blend知道如何处理您的控制。
2。)OnApplyTemplate覆盖。您可以在此处从模板中提取特定元素。这些被称为“部件”,您将在Blend中看到部件选项卡。 #1中的属性可以定义模板中的“部件”以及预期的类型。
3.)构造函数中的DefaultStyleKey = typeof(...)。这告诉Silverlight在generic.xaml中使用什么默认模板
4.看看Themes \ generic.xaml。这是一个特殊的硬编码文件位置,用于存储所有默认模板。搜索DatePicker样式,你会得到这个想法:)
祝你好运!答案 1 :(得分:2)
我只是想让你知道,我是如何实现它的。事实证明,根本没有必要为此编写自定义控件或UserControls。我所做的就是为汽车,船舶,渡轮,卡车等ViewModels编写数据表。例如,FerryViewModel的datatemplate包含一个ItemsControl,其ItemsPanel的类型为Canvas(能够定位卡车)和一个ItemTemplate,它是一个用于TruckViewModel的DataTemplate。一种非常简单快速的方法。
答案 2 :(得分:1)
我建议让一个用户控件处理所有绘图。否则你可能会迷失对象的层次结构。此外,如果添加了另一个项目,比如汽车,卡车和渡轮的人员,也会更容易。
如果您的模型是分层的,那么您可以将顶层传递到控件中,然后让控件自行排序。
MVVM适用于现有控件,但现有的WPF控件仅在控件接近您需要的控件时才有效,并且只需进行一些调整即可。我想不出WPF中的标准控件是否接近你需要的,所以是时候编写一个新的控件。答案 3 :(得分:0)
WPF在视图模型中的效果非常好。如果您可以在特定需要之前保留代码,那么您可以更轻松地将ui与数据分开。如果数据模型在不同显示之间没有变化,它将允许您的ui更加可升级。