Я использую mvvm для разработки приложения sl4 службы RIA, и мне, кажется, что-то не хватает.

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
GriffinHeart 30 Авг 2011 в 16:59

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 вам действительно не нужно вносить какие-либо изменения.

3
Jose 30 Авг 2011 в 19:01

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

0
avanek 30 Авг 2011 в 13:33

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

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