我一直在使用mvvm来开发一个RIA服务sl4应用程序,我似乎错过了一些东西。
当您的数据以预期的编辑格式或数据对象“适合视图”(网格,列表等)时,MVVM和数据绑定很有用。但是当你的数据没有直接映射时会发生什么?
我的例子
假设我有一个产品表,这定义了产品的价格和选项。我有一个订阅的产品表,它将链接产品和客户端,并且还有关于订阅何时结束的数据......
所以,当我开始研究“购物清单”时,我就这样做了:
<ListBox x:Name="ShopList" Grid.Row="0" ItemsSource="{Binding Products}">
<DataTemplate>
<StackPanel Orientation="Horizontal">
<sdk:Label Content="{Binding ModuleName}" />
<sdk:Label Content="{Binding DateStart, Converter={StaticResource gridDateFormatter}}" />
<sdk:Label Content="{Binding DateEnd, Converter={StaticResource gridDateFormatter}}" />
<telerik:RadMaskedTextBox MaskedText="{Binding UnitsToBuy}" />
<sdk:Label Content="{Binding UnitStep}" />
<sdk:Label Content="{Binding TotalPrice}" />
</StackPanel>
</DataTemplate>
</ListBox>
所以我认为我会在我的ViewModel上将ItemsSource与Observable集合绑定
public ObservableCollection<Product> Products
但是现在我遇到了问题,UnitsToBuy不属于产品,不属于产品。我很想知道如何找到一种干净的方式来处理这些情况。假设我可以在该列表中包含任意数量的项目。
感谢。
答案 0 :(得分:3)
我认为你所要求的归结为视图需要具有更多属性的视图模型,而不是简单的模型。为什么不这样的东西。显然,下面的类应该实现INotifyPropertyChanged。
public class CartItem
{
public Product Product {get;set;}
public int UnitsToBuy {get;set;}
public int UnitsStep {get;set;}
public decimal TotalPrice
{
get { return Product.Price * UnitsToBuy;}
}
//more properties can be added if needed
}
public class ShoppingCartViewModel
{
public ObservableCollection<CartItem> Products {get;set;}
}
然后在xaml中你真的不需要做任何改变。
答案 1 :(得分:0)
我将创建一个新的Model类,它将包含Product和SubscribedProduct所需的内容。然后,您可以创建一个类别的Mapper,将更多以视图为中心的模型转换为以数据为中心的模型(Product and SubscribedProduct)。
答案 2 :(得分:0)
我总是专门为模型或模型组构建我的视图。因此,我知道期望什么属性,以及可能缺少哪些属性。
如果我知道某个属性可能丢失,我会写一个DataTrigger
来根据数据改变视图
例如,如果我有一个应该显示Products
和SubscribedProducts
的视图,我可能会使用DataTrigger
来确定要显示的DataTemplate
<Style TargetType="ListBoxItem">
<Setter Property="Template" Value="{StaticResource DefaultProductTemplate}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Converter={StaticResource ObjectToTypeConverter}}" Value="{x:Type local:SubscribedProductModel}">
<Setter Property="Template" Value="{StaticResource SubscribedProductTemplate}" />
</DataTrigger>
</Style.Triggers>
</Style>