WPF Prism框架下基于MVVM模式的命令、绑定、事件

  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>
View Code

  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="300" Width="300">
    <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="123" CommandParameterEx="567" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </myCommandEx:PrismCommandEx>
    </Grid>
</Window>
View Code

 

转载于:https://www.cnblogs.com/xhh-lite/p/3318965.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WPF Prism MVVM中,ViewModels通常用来承载与视图相关的逻辑代码和数据。而命令则是一种将用户界面操作与ViewModel中的方法绑定起来的技术。 在ViewModel中声明命令的方式如下: ```csharp public ICommand MyCommand { get; private set; } ``` 其中,ICommand是一个接口,它定义了执行命令所需的方法。通常情况下,我们使用Prism库提供的DelegateCommand或者CompositeCommand来实现ICommand接口。 DelegateCommand表示可以通过传递Action或者Func来实现ICommand接口的类,并且它是一个泛型类型。例如: ```csharp public DelegateCommand<string> MyCommand { get; private set; } ``` CompositeCommand则是一种可以组合多个ICommand对象的类。例如: ```csharp public CompositeCommand MyCompositeCommand { get; private set; } ``` 在ViewModel的构造函数中,我们需要为命令对象赋值。例如: ```csharp public MyViewModel() { MyCommand = new DelegateCommand<string>(ExecuteMyCommand); MyCompositeCommand = new CompositeCommand(); MyCompositeCommand.RegisterCommand(MyCommand); } ``` 其中,ExecuteMyCommand是我们自定义的方法,用于执行命令的操作。 在View中,我们可以通过以下方式将命令与用户界面操作绑定起来: ```xaml <Button Content="Click Me" Command="{Binding MyCommand}" CommandParameter="Hello World"/> ``` 其中,Binding语法用于绑定ViewModel中的属性。在Command属性中,我们绑定了ViewModel中的MyCommand属性,这意味着当用户点击按钮时,MyCommand所绑定的ExecuteMyCommand方法将被调用。 而CommandParameter属性则是用来传递参数的。在这个例子中,我们将字符串"Hello World"作为参数传递给了ExecuteMyCommand方法。 总之,在WPF Prism MVVM中,ViewModels命令代码是用来将用户界面操作与ViewModel中的逻辑代码和数据绑定起来的一种技术,它可以有效地提高代码的可重用性和可维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值