日期:2014-05-17  浏览次数:20582 次

首发!!!基于windows8 winrt mvvm设计中的EventToExCommand

MVVM是Model-View-ViewModel的简写。
  微软的WPF带来了新的技术体验,如Sliverlight、音频、视频、3D、动画……,这导致了软件UI层更加细节化、可定制化。同时,在技术层面,WPF也带来了 诸如Binding、Dependency Property、Routed Events、Command、DataTemplate、ControlTemplate等新特性。MVVM(Model-View-ViewModel)框架的由来便是MVP(Model-View-Presenter)模式与WPF结合的应用方式时发展演变过来的一种新型架构框架。它立足于原有MVP框架并且把WPF的新特性揉合进去,以应对客户日益复杂的需求变化。
  WPF的数据绑定与Presentation Model相结合是非常好的做法,使得开发人员可以将View和逻辑分离出来,但这种数据绑定技术非常简单实用,也是WPF所特有的,所以我们又称之为Model-View-ViewModel(MVVM)。这种模式跟经典的MVP(Model-View-Presenter)模式很相似,除了你需要一个为View量身定制的model,这个model就是ViewModel。ViewModel包含所有由UI特定的接口和属性,并由一个 ViewModel 的视图的绑定属性,并可获得二者之间的松散耦合,所以需要在ViewModel 直接更新视图中编写相应代码。数据绑定系统还支持提供了标准化的方式传输到视图的验证错误的输入的验证。
 

在mvvm中有多种设计模式 例如 mvvmlight  caliburn prism 等等。 将codebehind 模式 转化为 mvvm 需要用到 xaml中强大的binding 和command。
 
在WPF中Icommand  只支持 传输Parameter 普通的参数,不少高手已经将其扩展,可传输多种事件 参数,还有的框架自带扩展例如(Mvvmlight)。
 
       

 但是在windows8 winrt  还没有发现在 Command binding 的事件中 同时传输 eventargs 和pamameters。。
 
    

 

以下将为大家 讲解如何在windows8 中 实现  eventToExCommand 


该实体用于在eventTocommand中传输  参数可以自定,

我为了 页面导航解耦 所以增加了一个 NavigateUrl ,如果嫌不够多还可以继续加。

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using Windows.UI.Xaml;

namespace TransvalueIntTourism.Com.Transvalue.Tools
{
    /// <summary>
    /// 扩展CommandParameter,使CommandParameter可以带事件参数
    /// </summary>
    public class ExCommandParameter
    {
        /// <summary>
        /// 事件触发源
        /// </summary>
        public DependencyObject Sender { get; set; }
        /// <summary>
        /// 事件参数
        /// </summary>
        public object EventArgs { get; set; }
        /// <summary>
        /// 额外参数
        /// </summary>
        public object Parameter { get; set; }

        /// <summary>
        /// 用于导航
        /// </summary>
        public string NavigateUrl { get; set; }
    }
}




 

下面是实现代码 以及思路:

using System.Collections.ObjectModel;
using System.Collections.Specialized;
using Windows.UI.Xaml;

namespace TransvalueIntTourism.Com.Transvalue.Tools
{
    public class EventToCommandCollection : ObservableCollection<EventToCommand>
    {
        internal FrameworkElement Element { get; set; }

        protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            // set parent element in each added eventtocommand
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                foreach (EventToCommand newItem in e.NewItems)
                {
                    newItem.Element = Element;
                }
            }

            // remove parent element in each removed eventtocommand
            if (e.Action == NotifyCollectionChangedAction.Remove)
            {
                foreach (EventToCommand newItem in e.NewItems)
                {
                    newItem.Element = null;
                }
            }
            base.OnCollectionChanged(e);
        }

        public static readonly DependencyProperty ItemsProperty =
            DependencyProperty.RegisterAttached(
                "ItemsPropertyInternal", // Shadow the name so the parser does not skip GetEventToCommandCollection
                typeof(EventToCommandCollection),
                typeof(EventToCommandCollection), null);

        public static EventToCommandCollection GetItems(FrameworkElement item)
        {
            var collection = (EventToCommandCollection)item.GetValue(ItemsProperty);
            if (collection == null)
            {
                collection = new EventToCommandCollection();