Шаблоны данных MVVM и непрямое отображение данных - PullRequest
3 голосов
/ 30 августа 2011

Я использую mvvm для разработки приложения RIA service 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>

Так что я подумал, что я собираюсь связать ItemsSource с коллекцией Observable на моей ViewModel

public ObservableCollection<Product> Products

Но теперь у меня есть проблема, UnitsToBuy - это то, чего нет в Продукте, и оно не принадлежит продукту. Я изо всех сил пытаюсь найти чистый способ справиться с подобными сценариями. Предположим, у меня может быть любое количество элементов в этом списке.

Спасибо.

Ответы [ 3 ]

3 голосов
/ 30 августа 2011

Я думаю, что вы спрашиваете, сводится к тому, что представление нуждается в модели представления с большим количеством свойств, а не в простой модели.Почему бы не иметь что-то подобное.Очевидно, что классы ниже должны реализовывать 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 вам не нужно вносить какие-либо изменения.

0 голосов
/ 30 августа 2011

Я всегда строю свои виды специально для модели или группы моделей. Поэтому я знаю, какие свойства ожидать, а какие могут отсутствовать.

Если я знаю, что свойство может отсутствовать, я напишу 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>
0 голосов
/ 30 августа 2011

Я бы создал новый класс Model, который будет содержать то, что вам нужно из Product и SubscribeedProduct. Затем вы можете создать своего рода Mapper, который преобразует модель, более ориентированную на представления, в ваши модели, ориентированные на данные (Product and SubscribeedProduct).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...