Prism框架下的自定义路由事件和命令绑定 BaseCode

  XAML代码:  

<Button x:Class="IM.UI.CommandEx.PrismCommandEx"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
</Button>

  CS代码:

    public partial class PrismCommandEx : Button
{
public PrismCommandEx()
{
InitializeComponent();
}
//定义一个路由事件 ClickTimeEx
private readonly RoutedEvent ClickTimeExEvent = EventManager.RegisterRoutedEvent("ClickTimeEx", RoutingStrategy.Bubble, typeof(EventHandler<PrintTimeRoutedEventArgs>), typeof(PrismCommandEx));
public event RoutedEventHandler ClickTimeEx
{
add { AddHandler(ClickTimeExEvent, value); }
remove { RemoveHandler(ClickTimeExEvent, value); }
}
private PrintTimeRoutedEventArgs routeEventArgs = null; //重写Button的OnClick事件,让Click事件去触发定义的ClickTimeEx事件
protected override void OnClick()
{
OnClickEx();
base.OnClick();
}
//定义一个路由事件的处理函数
private void OnClickEx()
{
if (routeEventArgs == null) routeEventArgs = new PrintTimeRoutedEventArgs(ClickTimeExEvent, this, DateTime.Now);
RaiseEvent(routeEventArgs);
}
}

PrismCommandEx

public class PrintTimeRoutedEventArgs : RoutedEventArgs
{
public PrintTimeRoutedEventArgs(RoutedEvent routeEvent, object source)
: base(routeEvent, source)
{ } public PrintTimeRoutedEventArgs(RoutedEvent routeEvent, object source, DateTime clickTime)
: this(routeEvent, source)
{
this.ClickTime = clickTime;
}
public DateTime ClickTime { get; set; }
}

PrintTimeRoutedEventArgs

public class InteractivesCommand : TriggerAction<DependencyObject>
{
private string commandName; //命令名称
//这里其实才是真正的执行命令的中转站,通过给定的命令去执行ViewModel
protected override void Invoke(object parameter)
{
if (this.AssociatedObject != null)
{
ICommand command = this.ResolveCommand();
object[] tempObj = { parameter, CommandParameter, CommandParameterEx };
if ((command != null) && command.CanExecute(tempObj))
{
command.Execute(tempObj);
}
}
} public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}
public static readonly DependencyProperty CommandProperty =
DependencyProperty.Register("Command", typeof(ICommand), typeof(InteractivesCommand), new UIPropertyMetadata(null)); public object CommandParameter
{
get { return (object)GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }
}
public static readonly DependencyProperty CommandParameterProperty =
DependencyProperty.Register("CommandParameter", typeof(object), typeof(InteractivesCommand), new UIPropertyMetadata(null, new PropertyChangedCallback((s, e) =>
{
InteractivesCommand ic = s as InteractivesCommand;
if (ic != null) ic.SynchronizeElementState();
}))); public object CommandParameterEx
{
get { return (object)GetValue(CommandParameterExProperty); }
set { SetValue(CommandParameterExProperty, value); }
}
public static readonly DependencyProperty CommandParameterExProperty =
DependencyProperty.Register("CommandParameterEx", typeof(object), typeof(InteractivesCommand), new UIPropertyMetadata(null, (s, e) =>
{
InteractivesCommand ic = s as InteractivesCommand;
if (ic != null) ic.SynchronizeElementState();
})); #region CRL属性
public string CommandName
{
get
{
this.ReadPreamble(); return this.commandName;
}
set
{
if (this.CommandName != value)
{
this.WritePreamble(); this.commandName = value; this.WritePostscript();
}
}
}
#endregion private void SynchronizeElementState()
{
ICommand command = this.Command;
if (command != null)
{
FrameworkElement associatedObject = this.AssociatedObject as FrameworkElement;
if (associatedObject != null)
{
associatedObject.IsEnabled = command.CanExecute(CommandParameter);
}
}
} private ICommand ResolveCommand()
{
ICommand command = null;
if (this.Command != null)
{
return this.Command;
}
//在注册命令的时,Command为NULL,通过命令名称去在当前的依赖存储环境变量中去查找这个命令,并返回命令
//貌似记忆中有印象,就是说所有的依赖属性,在WPF中都有存放在某一个散列的集合中,在这个依赖属性被使用的时间,才会去创建一个实例,好像是依赖属性的特性
if (this.AssociatedObject != null)
{
foreach (PropertyInfo info in base.AssociatedObject.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
if (typeof(ICommand).IsAssignableFrom(info.PropertyType) && string.Equals(info.Name, this.CommandName, StringComparison.Ordinal))
{
command = (ICommand)info.GetValue(base.AssociatedObject, null);
}
}
}
return command;
} }

InteractivesCommand

public class PrismViewModel
{
public PrismViewModel() { }
private DelegateCommand<Object> _commandWithEventArgs;
public ICommand ClickTimeExCommand //要绑定的命令
{
get { return _commandWithEventArgs ?? (_commandWithEventArgs = new DelegateCommand<object>(executeMethod, canExecuteMethod)); }
} private void executeMethod(Object parameter)
{
//parameter 接收的值来源于 InteractivesCommand 类重写的Invoke方法,构建的object[]数据
MessageBox.Show("Prism框架MVVM设计模式测试");
} private bool canExecuteMethod(Object parameter)
{
return true;
}
}

PrismViewModel

  控件调用:

<Window x:Class="IM.UI.WinPrismTest"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:myCommandEx="clr-namespace:IM.UI.CommandEx"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
Title="WinPrismTest" Height="" Width="">
<Window.DataContext>
<myCommandEx:PrismViewModel/>
</Window.DataContext>
<Grid>
<myCommandEx:PrismCommandEx x:Name="btnPrismMvvm" Content="Prism框架MVVM测试" VerticalAlignment="Top">
<i:Interaction.Triggers>
<i:EventTrigger EventName="ClickTimeEx">
<myCommandEx:InteractivesCommand Command="{Binding ClickTimeExCommand}" CommandName="ClickTimeExCommand" CommandParameter="" CommandParameterEx="" />
</i:EventTrigger>
</i:Interaction.Triggers>
</myCommandEx:PrismCommandEx>
</Grid>
</Window>

WPF Prism框架下基于MVVM模式的命令、绑定、事件的更多相关文章

  1. 【工作笔记二】ASP.NET MVC框架下使用MVVM模式

    ASP.NET MVC框架下使用MVVM模式 原文:http://www.cnblogs.com/n-pei/archive/2011/07/21/2113022.html 对于asp.net mvc ...

  2. 【转】ASP.NET MVC框架下使用MVVM模式-KnockOutJS+JQ模板例子

    KnockOutJS学习系列----(一) 好几个月没去写博客了,最近也是因为项目紧张,不过这个不是借口,J. 很多时候可能是因为事情一多,然后没法静下来心来去写点东西,学点东西. 也很抱歉,突然看到 ...

  3. ReactiveCocoa框架下的MVVM模式解读

    记录一些MVVM文章中关于ReactiveCocoa的代码: 实例一:带有分页的文章列表,根据文章类别过滤出文章的列表,可以进入文章详细页面 1:YFBlogListViewModel 首先了解关于列 ...

  4. MVVM模式的命令绑定

    命令绑定要达到的效果 命令绑定要关注的核心就是两个方面的问题,命令能否执行和命令怎么执行.也就是说当View中的一个Button绑定了ViewModel中一个命令后,什么时候这个Button是可用的, ...

  5. WPF自学入门(十一)WPF MVVM模式Command命令 WPF自学入门(十)WPF MVVM简单介绍

    WPF自学入门(十一)WPF MVVM模式Command命令   在WPF自学入门(十)WPF MVVM简单介绍中的示例似乎运行起来没有什么问题,也可以进行更新.但是这并不是我们使用MVVM的正确方式 ...

  6. WPF学习11:基于MVVM Light 制作图形编辑工具(2)

    本文是WPF学习10:基于MVVM Light 制作图形编辑工具(1)的后续 这一次的目标是完成 两个任务. 画布 效果: 画布上,选择的方案是:直接以Image作为画布,使用RenderTarget ...

  7. 在Jena框架下基于MySQL数据库实现本体的存取操作

    在Jena框架下基于MySQL数据库实现本体的存取操作 转自:http://blog.csdn.net/jtz_mpp/article/details/6224311 最近在做一个基于本体的管理系统. ...

  8. WPF学习12:基于MVVM Light 制作图形编辑工具(3)

    本文是WPF学习11:基于MVVM Light 制作图形编辑工具(2)的后续 这一次的目标是完成 两个任务. 本节完成后的效果: 本文分为三个部分: 1.对之前代码不合理的地方重新设计. 2.图形可选 ...

  9. 前端笔记之微信小程序(二){{}}插值和MVVM模式&数据双向绑定&指令&API

    一.双花括号{{}}插值和MVVM模式 1.1 体会{{}}插值 index.wxml的标签不是html的那些标签,这里的view就是div. {{}}这样的插值写法,叫做mustache语法.mus ...

随机推荐

  1. .net学习路线

    http://www.cnblogs.com/huangmeimujin/archive/2011/08/08/2131242.html http://jingyan.baidu.com/articl ...

  2. 为什么32位操作系统最大支持4GB内存

    因为32位操作系统的地址空间为32位,地址总数为2^32,每个地址对应1Byte内存空间,这样,32位操作系统管理的最大内存空间限制为2^32Byte=4*1024*1024*1024Byte,即4G ...

  3. JAVA中用于处理字符串的“三兄弟”

    JAVA中用于处理字符串常用的有三个类:java.lang.String.java.lang.StringBuffer.java.lang.StringBuilder,这三者的共同之处都是final类 ...

  4. 非常完整的PHP的mysql类

    非常完整的PHP的MySQL操作类, 即使PDO, ActiveRecord, ORM, 框架, Framework… 都不如这个强大和好用. 有了它, 你就不会再需要任何MySQL封装了,此类已经在 ...

  5. Discuz教程:X3.1-x3.2后台admin.php防止直接恶意访问

    功能说明:admin.php是discuz默认的后台地址,正常情况下可以直接访问,为了防止某些恶意访问的情况,可以修改以下内容进行安全性能提升.适用版本:Discuz!x1-x3.2具体实施方案: a ...

  6. HDU3068(Manacher算法)

    最长回文 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  7. HDU3410(单调队列)

    Passing the Message Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  8. [C#]为微软ASP.NET官方教学视频增加字幕

    前言 Microsoft Virtual Academy提供了学习ASP.NET的大量视频材料.(注1) 由于视频服务器位于海外,国内浏览速度并不理想,幸好官方提供了视频的下载地址以及英文字幕文件. ...

  9. iOS核心笔记—源代码管理工具-SVN

    源代码管理工具-SVN 一. 源代码管理工具概述 1. 源代码管理工具的作用? > 能追踪一个项目从诞生一直到定案的过程 > 记录一个项目的所有内容变化,无限制返回 > 查看特定版本 ...

  10. ECMAScript 6 笔记(五)

    Iterator和for...of循环 1. Iterator(遍历器)的概念 Iterator接口的目的,就是为所有数据结构,提供了一种统一的访问机制,即for...of循环 遍历器(Iterato ...