Silverlight MVVM标头详细信息

Silverlight MVVM标头详细信息,silverlight,mvvm,header,detail,Silverlight,Mvvm,Header,Detail,假设我有一个OrderModel和一个OrderViewModel。我在ViewModel和模型上都有供应商、订单日期等属性,它们是链接在一起的。这方面的例子已经看过了,而且似乎已经足够严格了,尽管在编写setter/getter方面有些重复 现在我该如何处理OrderDetails?在我的模型中,我会有一个列表 我是否有OrderDetail的OrderDetailViewModel?如果是,那么OrderViewModel是如何提供的?作为一个可观察的集合?如果是这样的话,你如何与原始列表保

假设我有一个OrderModel和一个OrderViewModel。我在ViewModel和模型上都有供应商、订单日期等属性,它们是链接在一起的。这方面的例子已经看过了,而且似乎已经足够严格了,尽管在编写setter/getter方面有些重复

现在我该如何处理OrderDetails?在我的模型中,我会有一个列表

我是否有OrderDetail的OrderDetailViewModel?如果是,那么OrderViewModel是如何提供的?作为一个可观察的集合?如果是这样的话,你如何与原始列表保持同步


这就是我没有看到一个好例子的地方。如果有人能给我指一指,我会很感激的。我相信MVVM的概念,但我开始觉得它的开销太大了。为什么不让ViewModel也处理模型零件呢。在日常LOB应用程序中,为了保证真正的MVVM所需的所有代码,两者之间真的有那么大的差异吗?

看起来这就是您所需要的:

谷歌的翻译将此作为演讲的摘要:

Silverlight 2在今年秋天发布,并为想要基于其创建富互联网应用(RIA)的开发者奠定了良好的基础。净。在本课程中,我们将深入介绍Silverlight 2的发展以及选择Silverlight 2作为以数据为中心的业务应用程序平台的好处。本课程将包括通过安全WCF服务进行的数据访问、如何使用模型-视图-模型模式(MVVM)构造代码、如何编写代码、设计师可以使用的代码以及开发人员的简单混合技巧。该会话将围绕一个潜水日志应用程序构建,在该应用程序中,代码将在演示后可用。 然而,与此同时,Jonas已经在这里谈到了MVVM:


您可以使用类似的方法来保持模型和视图模型之间的可观测采集同步:

/// <summary>
/// Keeps one collection synchronised with another.
/// </summary>
/// <typeparam name="Source">The type of the source items.</typeparam>
/// <typeparam name="Destination">The type of the destination items.</typeparam>
public class CollectionSync<Source, Destination>
{
    private readonly Func<Source, Destination> _destItemFactory;
    private readonly Action<Destination>       _destItemRemover;

    private readonly IList<Destination> _destList;
    private readonly IList<Source>      _sourceList;

    /// <summary>
    /// Initializes a new instance of the <see cref="CollectionSync&lt;Source, Destination&gt;"/> class.
    /// </summary>
    /// <param name="sourceList">The source list.</param>
    /// <param name="destList">The destination list.</param>
    /// <param name="destItemFactory">Factory method which creates a Destination for a given Source.</param>
    /// <param name="destItemRemover">Method called when a Destination is removed.</param>
    public CollectionSync(IList<Source> sourceList,
                          IList<Destination> destList,
                          Func<Source, Destination> destItemFactory,
                          Action<Destination> destItemRemover)
    {
        _destItemFactory = destItemFactory;
        _destItemRemover = destItemRemover;
        _sourceList = sourceList;
        _destList = destList;

        ((INotifyCollectionChanged) _sourceList).CollectionChanged += SourceCollection_CollectionChanged;

        PopulateWithAllItems();
    }

    private void PopulateWithAllItems()
    {
        foreach (Source sourceItem in _sourceList)
            _destList.Add(_destItemFactory(sourceItem));
    }

    private void SourceCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs args)
    {
        switch (args.Action)
        {
            case NotifyCollectionChangedAction.Add:
                OnItemsAdded(args.NewStartingIndex, args.NewItems);
                break;
            case NotifyCollectionChangedAction.Remove:
                OnItemsRemoved(args.OldStartingIndex, args.OldItems);
                break;
            case NotifyCollectionChangedAction.Reset:
                OnItemsReset();
                break;
            case NotifyCollectionChangedAction.Move:
            case NotifyCollectionChangedAction.Replace:
                throw new NotImplementedException();
        }
    }

    private void OnItemsReset()
    {
        _destList.Clear();
        PopulateWithAllItems();
    }

    private void OnItemsRemoved(int index, ICollection items)
    {
        int itemCount = items.Count;
        for (int i = 0; i < itemCount; i++)
        {
            Destination removed = _destList[index];
            _destList.RemoveAt(index);
            if (_destItemRemover != null)
                _destItemRemover(removed);
        }
    }

    private void OnItemsAdded(int index, IList items)
    {
        int itemIndex = index;
        foreach (Source item in items)
        {
            // Add to Items collection
            _destList.Insert(itemIndex, _destItemFactory(item));
            itemIndex++;
        }
    }
}
//
///使一个收藏与另一个收藏保持同步。
/// 
///源项的类型。
///目标项目的类型。
公共类集合同步
{
私有只读函数destinemfactory;
私有只读操作_destinemover;
私有只读IList_destList;
私有只读IList_sourceList;
/// 
///初始化类的新实例。
/// 
///源列表。
///目的地列表。
///为给定源创建目标的工厂方法。
///方法在删除目标时调用。
公共集合同步(IList sourceList,
IList destList,
Func DestinemFactory,
行动目标(删除程序)
{
_DestinemFactory=DestinemFactory;
_DestinemRemover=DestinemRemover;
_sourceList=sourceList;
_destList=destList;
((INotifyCollectionChanged)\u sourceList.CollectionChanged+=SourceCollection\u CollectionChanged;
用allitems()填充;
}
private void PopulateWithAllItems()
{
foreach(源列表中的源sourceItem)
_destList.Add(_destemfactory(sourceItem));
}
私有void SourceCollection\u CollectionChanged(对象发送方,NotifyCollectionChangedEventArgs args)
{
开关(参数操作)
{
案例NotifyCollectionChangedAction。添加:
OnItemsAdded(args.NewStartingIndex,args.NewItems);
打破
案例NotifyCollectionChangedAction。删除:
已删除OnItems(args.OldStartingIndex、args.OldItems);
打破
案例通知CollectionChangedAction.Reset:
msreset();
打破
案例通知收集更改操作。移动:
案例通知收集更改操作。替换:
抛出新的NotImplementedException();
}
}
私有空间重置()
{
_destList.Clear();
用allitems()填充;
}
已删除专用索引(整型索引、ICollection项)
{
int itemCount=items.Count;
对于(int i=0;i
以Order/OrderDetails为例,在Order视图模型中,您可以像这样连接两个ObservableCollection:

_modelToViewModelSync = new CollectionSync<IOrderDetail, OrderDetailViewModel>(
    orderDetailModels,                 // the list of your order details models
    OrderDetails,                      // the list of order details view models exposed by the Order view model
    x => new OrderDetailViewModel(x),  // factory method to create a view model
    null);                             // do something here if you care when your view models are removed
\u modelToViewModelSync=newcollectionsync(
orderDetailModels,//订单详细信息模型的列表
OrderDetails,//订单视图模型公开的订单详细信息视图模型列表
x=>new OrderDetailViewModel(x),//用于创建视图模型的工厂方法
空);//如果您介意删除视图模型,请在此处执行操作

当谈到“我需要另一个视图模型吗”这个问题时,我的回答是:如果您的视图所做的一切都是显示模型数据,那么直接绑定到订单没有什么害处。为此创建ViewModel将是非常多余的。需要创建ViewModel的时间是“订单详细信息”屏幕中需要表示的逻辑或状态。此时将创建一个ViewModel,而不是将其添加到模型中

至于保持这些项目的同步,类似于GraemeF,我创建了一个活页夹类,它使用反射将两个值绑定在一起。它使我的模型和viewmodel属性保持同步,并可用于保持其他内容