Windows Phone 开发笔记 (2) Command

本文同步发表于 Windows Phone论坛 WPDEVN :http://www.wpdevn.com/showtopic-138.aspx

 

在上一篇开发笔记中我么聊了ViewModel 这一次我们来说说Command VM中我们一些方法需要提供给view 使用。其中最简单的方法是直接暴露一个public 的方法由view(xmal.cs) 中直接调用。如果我们想把这个方法绑定到页面(xaml) 中的事件则需要使用Command. 当然在xmal.cs 中也可以直接使用Command

 

View 想使用Command 那么首先必须在VM 实现一个公开的Command属性。

Windows Phone SDK  Command的实现必须继承与System.Windows.Input.ICommand接口ICommand 中包含CanExecute Execute 方法和一个CanExecuteChanged 事件。

 

如果Command 是被绑定到页面上的事件中。那么系统在执行Command的时候将先执行 CanExecute 方法
如果方法返回true则执行Execute方法的方式来执行Command。在调用这两个方法的时候Command的参数均会被传入这两个方法。

同时我们建议是自己调用Command使用的话也建议遵循这样的方式。

 

在使用Command使用必然会增加代码量,当然也带来好处:

1、
可以直接绑定

2、
可以控制状态

 

现在我们先来Command如何实现。一般来说我在代码中实现一个基础的通用Command,已代理的方式在Command 构建的时候传入Execute 方法和CanExecute的具体逻辑。


代码如下:

 

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace WeiFan.Utility.Command
{
    public class DelegateCommand<T> : ICommand where T : class
    {
        Action<T> m_excuteAction;
        Func<T, bool> m_canExcunteFunc;

        public DelegateCommand(Action<T> excuteAction)
        {
            m_excuteAction = excuteAction;
        }
        public DelegateCommand(Action<T> excuteAction, Func<T, bool> canExcuteAction)
        {
            m_canExcunteFunc=canExcuteAction;
            m_excuteAction = excuteAction;
        }

        private bool m_isCanExecute = true;
        public bool IsCanExecute
        {
            get { return m_isCanExecute; }
            set
            {
                if (value != m_isCanExecute)
                {
                    m_isCanExecute = value;
                    FireCanExecuteChanged();
                }

            }
        }

        private void FireCanExecuteChanged()
        {
            if (CanExecuteChanged !=null)
                CanExecuteChanged(this, new EventArgs());
        }

        #region ICommand Members

        public event EventHandler CanExecuteChanged;

        public bool CanExecute(object parameter)
        {
            if (m_canExcunteFunc == null)
            {
                return IsCanExecute;
            }
            else
            {
                T args;

                args = parameter as T;


                IsCanExecute = m_canExcunteFunc(args);
            }
            return IsCanExecute;
        }

        public void Execute(object parameter)
        {
            if (m_excuteAction != null)
            {
                T args;

                args = parameter as T;

                m_excuteAction(args);
            }
        }


        #endregion
        
    }
}

 


其中泛型T为Command 参数类型。
那么 我们在VM 中使用该Command 如下:

private DelegateCommand<string> m_clickImageCommand;
        public ICommand ClickImageCommand { get { return m_clickImageCommand; } }

注意这个Command 是调用的时候接受一个 string 类型的参数。 这个Command的CanExecute 永远返回True 也就是说无论什么时候 该Command 都可以执行。

接下来我们来聊聊Command 的参数
首先Command在使用的是有允许传入一个 Object 类型的参数。 如果我们的Command 只接收一个参数到好说 在泛型里面限定类型就OK 了。。。  如果要接受多个参数的话就很蛋疼了。。 
在这里我选择采用 一个集合类型将多个参数打包成一个集合传入Command。 
考虑到为了让其使用起来友好 又能方便绑定我选择该集合采用简直对的方式 集合中的每个元素包含一个key 和一个value . 元素可以使用index  来索引 可以使用key 来索引。

代码如下:
CommandArg:

[ContentProperty("Value")]
    public class CommandArg : DependencyObject, IEquatable<CommandArg>
    {

        public CommandArg(string key, Object value)
        {
            this.Key = key;
            this.Value = value;
        }

        public CommandArg() { }

        private const string KEY_CAN_NOT_NULL = "绑定参数的key不能为空";

        #region DependencyProperty


        private static readonly DependencyProperty KeyProperty = DependencyProperty.Register("Key", typeof(string), typeof(CommandArg), new PropertyMetadata(new Random().Next().ToString(), KeyPropertyChanged));
        
        private static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(Object), typeof(CommandArg), new PropertyMetadata(null));

        private static void KeyPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            if (string.IsNullOrWhiteSpace(Convert.ToString(e.NewValue)) && string.IsNullOrEmpty(Convert.ToString(e.NewValue)))
                throw new Exception(KEY_CAN_NOT_NULL);
        }

        bool m_isSetKey = false;
      
        public string Key
        {
            get { return Convert.ToString(GetValue(KeyProperty)); }
            set 
            {
                if (string.IsNullOrWhiteSpace(Convert.ToString(value)))
                {
                    throw new ArgumentException(KEY_CAN_NOT_NULL);
                }
                else
                {
                    if (m_isSetKey == false)
                    {
                        SetValue(KeyProperty, value);
                        m_isSetKey = true;
                    }
                    else
                    {
                        throw new InvalidOperationException("KEY_HAS_BEEN_SET");
                    }

                }
            }
        }

            
        public Object Value
        {
            get { return GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }

        #endregion

        public override string ToString()
        {
            return string.Format("({0},{1})", this.Key, this.Value);
        }

        

        #region IEquatable接口实现

        public bool Equals(CommandArg other)
        {
            if (other == null) return false;
            return string.Equals(Key, other.Key, StringComparison.InvariantCultureIgnoreCase) && Value == other.Value;
        }

        #endregion
    }

这是集合中单个元素对象

CommandArgs:

using System;
using System.Collections;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using WeiFan.Utility.Command;

namespace WeiFan.Utility.Command
{
    public class CommandArgs: DependencyObjectCollection<CommandArg>
    {
        public CommandArgs():
            base()
        {
            base.Clear();
            
            base.CollectionChanged += new NotifyCollectionChangedEventHandler(CommandArgs_CollectionChanged);
            
        }

        

        void CommandArgs_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Add && e.NewItems!=null)
            {
                foreach (CommandArg arg in e.NewItems)
                {
                    CommandArg containArg = GetItemByKey(arg.Key);

                    if (containArg != null && !containArg.Equals(arg))
                    {
                        throw new Exception("The collection contains this key");
                    }
                }
            }
        }

         

        public new void SetValue(DependencyProperty dp, object value)
        {
            //System.Diagnostics.Debug.WriteLine("SetValue");
            base.SetValue(dp, value);
        }

        public bool Contains(string key)
        {
            if (GetItemByKey(key) == null)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
    

        public new void Add(CommandArg item)
        {
          
            if (GetItemByKey(item.Key) != null)
            {
                throw new Exception("The collection contains this key");
            }
            else
            {
                base.Add(item);
            }
        }

      
        private CommandArg GetItemByKey(string key)
        {
            if (!String.IsNullOrEmpty(key) && !String.IsNullOrWhiteSpace(key))
            {
                for (int i = 0; i < base.Count; i++)
                {
                    CommandArg arg = base[i];
                    if (arg.Key == key)
                    {
                        return arg;
                    }
                }
            }
            return null;
        }

        /// <summary>
        /// 索引器
        /// </summary>
        /// <param name="key">Key</param>
        /// <returns></returns>
        public CommandArg this[string key]
        {
            get 
            {
                return GetItemByKey(key);
            }
            set 
            {
                CommandArg arg = GetItemByKey(key);
                if (arg == null)
                {
                    throw new NullReferenceException();
                }
                else
                {
                    arg = value;
                }
            }
        }
       
    }
}

这是参数集合

 

好了。 接下来的事情我们就来看下 VM 中的Command 如何使用了 

先看简单的吧 xaml.cs 中使用: 

if (m_statusVM.LoadComand.CanExecute(null))
            {
                m_statusVM.LoadComand.Execute(null);
            }

这里该是什么参数就在CanExecute 和 Execute 里面传什么参数


如果想在xaml 中绑定command 的话 需要使用Trigger 将Command和控件事件绑定起来: 
代码如下:

<Image x:Name="imgMyImage" VerticalAlignment="Top"  Width="75" Height="75" Source="{Binding Path=Status.User.ProfileImageUrl}" >
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="Tap">
                                <i:InvokeCommandAction Command="{Binding Path=ClickUserCommand}"></i:InvokeCommandAction>
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </Image>

在这里 当Image 的Tap 事件触发的时候 调用 ClickUserCommand 事件 这个Command 没有参数传入。
注意 i是:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"  

工程需要引用 Microsoft.Expression.Interactions 

如果需要传入参数 那么代码如下:

<Image x:Name="imgMyImage" VerticalAlignment="Top"  Width="75" Height="75" Source="{Binding Path=Status.User.ProfileImageUrl}" >
                        
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="Tap">
                                <i:InvokeCommandAction Command="{Binding Path=ClickUserCommand}">
                                    <i:InvokeCommandAction.CommandParameter>
                                        <Command:CommandArgs>
                                            <Command:CommandArg Value="sdf" Key="1"></Command:CommandArg>
                                            <Command:CommandArg Value="sdf" Key="2"></Command:CommandArg>

                                        </Command:CommandArgs>    
                                    </i:InvokeCommandAction.CommandParameter>
                                </i:InvokeCommandAction>
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                    </Image>

注意这里的Command: 的定义是    
xmlns:Command="clr-namespace:WeiFan.Utility.Command;assembly=WeiFan.Utility"     该namespace是DelegateCommand 、CommandArg 和 ComandArgs 的定义所在位置

这里我们想ClickUserCommand 中 CommandArgs 集合对象 集合中有两个CommanArg元素 key 分别为1 和2 .

 

 

 

 

 

 

转载于:https://www.cnblogs.com/JerryH/archive/2012/04/30/2477259.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
1. 智慧监狱概述 智慧监狱的建设背景基于监狱信息化的发展历程,从最初的数字化监狱到信息化监狱,最终发展到智慧监狱。智慧监狱强调管理的精细化、监管的一体化、改造的科学化以及办公的无纸化。政策上,自2017年以来,司法部连续发布了多项指导性文件,推动智慧监狱的建设。 2. 内在需求与挑战 智慧监狱的内在需求包括数据应用与共享的不足、安防系统的单一功能、IT架构的复杂性、信息安全建设的薄弱以及IT运维的人工依赖。这些挑战要求监狱系统进行改革,以实现数据的深度利用和业务的智能化。 3. 技术架构与设计 智慧监狱的技术架构包括统一门户、信息安全、综合运维、安防集成平台和大数据平台。设计上,智慧监狱采用云计算、物联网、大数据和人工智能等技术,实现资源的动态分配、业务的快速部署和安全的主动防护。 4. 数据治理与应用 监狱数据应用现状面临数据分散和共享不足的问题。智慧监狱通过构建数据共享交换体系、数据治理工具及服务,以及基于数据仓库的数据分析模型,提升了数据的利用效率和决策支持能力。 5. 安全与运维 智慧监狱的信息安全建设涵盖了大数据应用、安全管理区、业务区等多个层面,确保了数据的安全和系统的稳定运行。同时,综合运维平台的建立,实现了IT系统的统一管理和自动化运维,提高了运维效率和系统的可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值