los*_*wpf 14 wpf wcf prism smartclient mvvm
我在该领域的经验非常少,我正在编写一个使用MVVM与WCF后端通信的WPF智能客户端应用程序,并且我真的很难从所有信息中做出正确的决策.这引出了一系列问题,我希望在这方面有更多经验的人可以解决这些问题.
例如,其中一个屏幕将允许输入订单并向订单添加订单行.
什么用作模型?
在WCF服务上,我有以下简化的DTO:
public OrderDTO
{
string orderDetails { get; set; }
List<OrderLineDTO> OrderLines { get; set; }
}
public OrderLineDTO
{
int customerId { get; set; }
int productId { get; set; }
double quantity { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
和WCF服务有以下方法:
public OrderService Order
{
CreateOrderResponse CreateOrder(OrderDTO order)
}
Run Code Online (Sandbox Code Playgroud)
在我的WPF智能客户端中,我有一个对DTO的引用,但显然它没有实现,INotifyPropertyChanged
因为它纯粹是为了传输.
问题
建议的方法是将这些DTO转换为INotifyPropertyChanged
使用Automapper或类似方法实现的模型吗?或者DTO应该直接在ViewModel中用作模型?
在视图模型之间进行通信
目前,我有一个带有ViewModels 和2的标签(Order
和OrderLines
)的订单视图.在订单选项卡上,我有一个包含客户ID和名称.当我选择客户时,我需要告知客户已被选中,以便仅显示属于该客户的产品.OrderViewModel
OrderLineViewModel
ComboBox
OrderView
OrderLineView
ComboBox
问题
在这种情况下如何OrderViewModel
沟通OrderLineViewModel
?
添加订单行并应用逻辑/业务规则
由于服务器级应用程序将由多个客户端使用,例如PC,移动设备..我想确保所有业务规则都应用于服务器级应用程序.例如,添加订单行时.如果是某种产品类型,只有在客户有特定认证的情况下才能添加.
但是,我所读到的关于MVVM的所有内容都表明该模型适用于业务规则和行为 - 所有这些示例都在客户端实现了该模型.理想情况下,我不想在客户端和服务器上复制相同的检查,所以我想知道如何确保不会发生这种情况.
问题
您是否允许用户添加无效行,将请求发送到服务器,让服务器应用相关规则并返回响应?或者,在将请求发送到服务器之前,您是否以某种方式在智能客户端应用程序中应用逻辑?
我真的希望在这里概述的所有领域都做得更好,我提前感谢你的任何回复.
谢谢
亚历克斯
编辑: 感谢大家的贡献,因为它帮助我在最佳前进方面变得更加清晰.所有答案都很好,但我决定接受Uri的回答,因为它最符合我现阶段的想法.但是,我仍然不确定处理从DTO的Id到ItemsSource中的SelectedItem的转换的最佳方法,ItemsSource是ViewModel的列表.我可以看到转换器可能有效,但我将尝试找到另一种解决方案.谢谢Alex
以下是我对你的问题的思考:
问题: 推荐的方法是将这些 DTO 转换为使用 Automapper 或类似工具实现 INotifyPropertyChanged 的模型吗?或者应该直接在视图模型中使用 DTO 作为模型?
答:我最喜欢的方法是遏制。我同意你的观点,DTO 除了 getter 和 setter 之外不应该有任何东西。尽可能保持干净,因此它不应该触发 INotifyPropertyChanged。我也不认为视图应该直接访问对象模型(如果没有其他原因,您没有属性更改的好处)。我的方法的缺点是 ViewModel 中有一些额外的代码,但我认为这是值得的。
public class VmBase : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void raise( string propName )
{
if( PropertyChanged ) {
PropertyChanged( this, new PropertyChangedEventArgs(propName) );
}
}
}
public class OrderLineVm : VmBase {
private OrderLineDTO orderLine;
public OrderLineVm( OrderLineDTO ol ) {
orderLine = ol;
}
public OrderLineVm( ) {
orderLine = new OrderLineDTO();
}
int customerId {
get { return orderLine.customerId; }
set { orderLine.customerId=value; raise("customerId"); }
}
int productId {
get { return orderLine.productId; }
set { orderLine.productId=value; raise("productId"); }
}
double quantity {
...
}
}
Run Code Online (Sandbox Code Playgroud)
通过垃圾收集的奇迹,OrderLineDTO 将仅创建一次(当它来自服务器时),并且只要需要它就一直存在。有两种公共构造函数:一种带有 DTO(通常,当对象来自服务器时),另一种在客户端上创建。
对于 OrderVm 来说,这有点复杂,因为您希望有一个 OrderLineVm(相对于 OrderLineDTO)的 ObservableCollection(相对于 List),所以包含不起作用。另请注意,orderLines 只有一个 getter(您可以从中添加和删除订单行,但不会更改整个列表。在构造期间分配一次)。
public class OrderVm : VmBase {
private string _orderDetails;
public string orderDetails {
get { return _orderDetails;
set { _orderDetails=value; raise("orderDetails"); }
}
private ObservableCollection<OrderLineVm> _orderLines;
public ObservableCollection<OrderLineVm> orderLines {
get { return _orderLines; }
}
}
Run Code Online (Sandbox Code Playgroud)
问题: 在这种情况下,OrderViewModel 将如何与 OrderLineViewModel 通信?
答:如果需要沟通,确实应该以最简单的方式进行。两个视图模型类位于同一层。OrderVm 引用了 OrderLineVm 的列表,如果您需要从 OrderLineVm 类到订单的通信,只需保留一个引用即可。
然而,我强烈认为不需要沟通。一旦视图被适当地绑定,我认为没有理由进行这种通信。绑定的 Mode 属性应该是“双向”,因此 UI 中更改的所有内容都将在视图模型中更改。由于 ObservableCollection 发送的通知,对订单行列表的添加、删除将自动反映在视图上。
问题:是否允许用户添加无效行,将请求发送到服务器,让服务器应用相关规则并返回响应?或者,在将请求发送到服务器之前,您是否以某种方式应用智能客户端应用程序中的逻辑?
答:除了服务器之外,在客户端进行数据验证并没有什么问题。避免重复代码 - 使用单个程序集(可能是定义 DTO 的程序集)来执行验证,并在客户端中部署该程序集。这样您的应用程序的响应速度将会更快,并且您将减少服务器上的工作负载。
显然,您需要在服务器上进行数据验证(出于安全原因和竞争冲突)。即使客户端上的验证已通过,您也必须处理服务器返回错误的情况。
编辑:(跟进亚历克斯的评论):
显示下拉列表:我认为您困惑的根源在于实际上有两个独立的 ItemsSource(因此有两个独立的数据上下文):有一个订单行列表,每个订单行中嵌入的是 ProductID 列表,其中是填充组合框的项目。只有 SelectedItem 是 ProductLine 的属性。通常,可能的 ProductID 列表对于应用程序(或订单)应该是全局的。您将拥有整个表单的 ProductID 属性,并为其指定一个名称(例如 x:Key 或 x:Name)。然后,在 ComboBox 元素中只需引用此列表:
<ComboBox ItemsSource="{Binding Source={StaticResource ProductIDs}}"
SelectedItem="{Binding Path=productId}"
/>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2688 次 |
最近记录: |