• 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
  • 相关阅读:
    Clouds
    docs
    虚拟化监控问题
    Openstack Ceilometer监控项扩展
    openStack ceilometer API
    sql分级汇总
    【Android归纳】阿里笔试题之Android网络优化
    享元模式
    【Hibernate步步为营】--核心对象+持久对象全析(三)
    Linux经常使用命令(三)
  • 原文地址:https://www.cnblogs.com/xhh-lite/p/3318965.html
Copyright © 2020-2023  润新知