【问题标题】:MVVM data templates and non-direct data mappingMVVM 数据模板和非直接数据映射
【发布时间】:2011-08-30 12:59:21
【问题描述】:

我一直在使用 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 不在产品中,也不属于产品。我正在努力寻找一种干净的方法来处理这些情况。假设我可以在该列表中包含任意数量的项目。

谢谢。

【问题讨论】:

  • UnitsToBuy 是另一个模型对象的一部分,还是它本身?我想我的问题是您是否要尝试将两个模型合并在一起。
  • @avanek 好吧,它将用于另一个模型,比如说 SubscribedProduct 模型/表

标签: xaml silverlight-4.0 mvvm


【解决方案1】:

我认为您的问题归结为视图需要具有更多属性的视图模型,而不是简单模型。为什么没有这样的东西。显然,下面的类应该实现 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 中您实际上不需要进行任何更改。

【讨论】:

    【解决方案2】:

    我将创建一个新的模型类,该类将包含您需要的产品和订阅产品。然后,您可以创建一个映射器,将更多以视图为中心的模型转换为以数据为中心的模型(产品和订阅产品)。

    【讨论】:

      【解决方案3】:

      我总是专门为一个模型或一组模型构建我的视图。因此,我知道需要哪些属性,哪些属性可能会丢失。

      如果我知道某个属性可能会丢失,我会写一个DataTrigger 来根据数据更改视图

      例如,如果我有一个应该显示 ProductsSubscribedProducts 的视图,我可能会使用 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>
      

      【讨论】:

      • 不要以为那是我要找的东西,我不是想显示产品和订阅的产品,我想显示产品的购物清单,但它本身就是它的描述不是它的“选项”(购买多少个单位)。这似乎不适合控件的绑定机制。
      • @GriffinHeart 你需要一个不同的Model。不应期望您的产品跟踪要购买的单位数量和总价格,因为此类数据属于ProductOrder,而不是Product。您应该创建一个带有ProductAmountTotalPriceProductOrder 类,即Amount * Product.UnitPrice
      猜你喜欢
      • 2012-02-25
      • 2011-09-27
      • 1970-01-01
      • 2020-02-17
      • 2011-12-22
      • 2015-01-28
      • 2013-11-07
      • 2022-12-14
      • 2019-05-16
      相关资源
      最近更新 更多