[置顶] 首发!!!基于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();
                collection.Element = item;
                item.SetValue(ItemsProperty, collection);
            }
            return collection;
        }

        public static void SetItems(FrameworkElement item, EventToCommandCollection value)
        {
            item.SetValue(ItemsProperty, value);
        }
    }
}


 

下面是实现类:

using System;
using System.Reflection;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Windows.Input;
using Windows.UI.Core;
using Windows.UI.Xaml;

namespace TransvalueIntTourism.Com.Transvalue.Tools
{
    public class EventToCommand : FrameworkElement
    {
        #region RelayCommand

        public static readonly DependencyProperty CommandProperty =
            DependencyProperty.Register("Command", typeof(ICommand), typeof(EventToCommand),
                                        new PropertyMetadata(DependencyProperty.UnsetValue));

        public ICommand Command
        {
            get { return (ICommand)GetValue(CommandProperty); }
            set { SetValue(CommandProperty, value); }
        }

        #endregion

        #region RelayCommandParameter

        public static readonly DependencyProperty CommandParameterProperty =
              DependencyProperty.Register("CommandParameter", typeof(object), typeof(EventToCommand),
                                          new PropertyMetadata(DependencyProperty.UnsetValue));

        public object CommandParameter
        {
            get { return GetValue(CommandParameterProperty); }
            set { SetValue(CommandParameterProperty, value); }
        }

        #endregion

        #region NavigateUrl

        public static readonly DependencyProperty NavigateUrlProperty =
            DependencyProperty.Register("NavigateUrl", typeof(string), typeof(EventToCommand),
                                        new PropertyMetadata(DependencyProperty.UnsetValue));

        public string NavigateUrl
        {
            get { return (string)GetValue(NavigateUrlProperty); }
            set { SetValue(NavigateUrlProperty, value); }
        }

        #endregion


        #region RelayCommandEvent

        public static readonly DependencyProperty EventProperty =
            DependencyProperty.Register("Event", typeof(string), typeof(EventToCommand),
                                        new PropertyMetadata(DependencyProperty.UnsetValue));

        private FrameworkElement _element;

        public string Event
        {
            get { return (string)GetValue(EventProperty); }
            set { SetValue(EventProperty, value); }
        }

        #endregion

        public FrameworkElement Element
        {
            get { return _element; }
            set
            {
                _element = value;

                var eventinfo = _element.GetType().GetRuntimeEvent(Event);

                // if event not found, throw exception
                if (eventinfo == null)
                    throw new ArgumentException(string.Format("Event {0} not found on element {1}.", Event, Element.GetType().Name));

                //Get method to call when event raised
                var executemethodinfo = GetType().GetTypeInfo().GetDeclaredMethod("ExecuteCommand").CreateDelegate(eventinfo.EventHandlerType, this);

                // Register event
                WindowsRuntimeMarshal.AddEventHandler(
                    del => (EventRegistrationToken)eventinfo.AddMethod.Invoke(_element, new object[] { del }),
                    token => eventinfo.RemoveMethod.Invoke(_element, new object[] { token }), executemethodinfo);

            }
        }

        public void ExecuteCommand(object sender, object eventhandler)
        {
            // Set the DataContext to the element DataContext (Otherwise the binding returns NULL
            DataContext = Element.DataContext;
             Get the command
            //var command = Command;
            var ExCommandParameter = new ExCommandParameter();
            //Command is null, so don't do anything
            if (null == Command)
                return;
            if (null == CommandParameter)
                return;
            ExCommandParameter.EventArgs = eventhandler;
            ExCommandParameter.NavigateUrl = NavigateUrl;
            ExCommandParameter.Sender = sender as DependencyObject;
            ExCommandParameter.Parameter = CommandParameter;
            Command.Execute(ExCommandParameter);

        }
    }
}


 

下面
使用方法。

可将事件参数 以及 commandparameter 传输到 command 事件中

<GridViewItem>
                            <Image Height="280" Width="280" Source="{Binding IconUrl}"/>
                            <i:EventToCommandCollection.Items>
                                <i:EventToCommand Command="{Binding MenuCMD}"                                      
                                                  CommandParameter="{Binding NavigateParameter}"                                     
                                                  NavigateUrl="{Binding NavigateUrl}"
                                                  Event="PointerPressed"/>
                            </i:EventToCommandCollection.Items>
                        </GridViewItem>
  

 

 

#region Command
        private RelayCommand<ExCommandParameter> _menuCMD;

        /// <summary>
        /// Gets the MenuCMD.
        /// </summary>
        public RelayCommand<ExCommandParameter> MenuCMD
        {
            get
            {
                return _menuCMD ?? (_menuCMD = new RelayCommand<ExCommandParameter>(
                    ExecuteMenuCMD,
                    CanExecuteMenuCMD));
            }
        }

        private void ExecuteMenuCMD(ExCommandParameter url)
        {
            var nav = new NavigateParameter();
            nav.Parameter = url.Parameter;
            nav.PageType = url.NavigateUrl;
            Messenger.Default.Send<NavigateParameter>(nav, "MenuNavigate");
        }

        private bool CanExecuteMenuCMD(ExCommandParameter url)
        {
            if (null != url && !"".Equals(url))
                return true;
            else return false;
        }
        #endregion



 

 

 

如有疑问可以在博客内留言,近期会将demo整理并上传

 

 

转载于:https://www.cnblogs.com/wangrenzhu/archive/2012/09/09/2766821.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值