首页 > 其他分享 >wpf ICommand接口 MVVM

wpf ICommand接口 MVVM

时间:2023-07-16 10:33:08浏览次数:27  
标签:ICommand TargetExecuteMethod MVVM 代码 object 命令 wpf parameter public

先来点儿抽象的,在mvvm编程模式的命令中,有两个主要的角色,invoker和receiver

image

invoker

  • invoker是一段可以执行一定逻辑的代码
  • 一般的,它是在UI框架的context中的用户与之交互的UI元素。

receiver

  • receiver是invoker触发时会执行的逻辑
  • 在MVVM 中,receiver通常是viewmodel中需要被调用的方法

invoker和receiver不需要知道彼此的存在

ICommand接口

icommand接口的源代码为:

点击查看代码
public interface ICommand
    {
        /// <summary>
        /// Raised when the ability of the command to execute has changed.
        /// </summary>
        event EventHandler? CanExecuteChanged;
 
        /// <summary>
        /// Returns whether the command can be executed.
        /// </summary>
        /// <param name="parameter">A parameter that may be used in executing the command. This parameter may be ignored by some implementations.</param>
        /// <returns>true if the command can be executed with the given parameter and current state. false otherwise.</returns>
        bool CanExecute(object? parameter);
 
        /// <summary>
        /// Defines the method that should be executed when the command is executed.
        /// </summary>
        /// <param name="parameter">A parameter that may be used in executing the command. This parameter may be ignored by some implementations.</param>
        void Execute(object? parameter);
    }

个人的简单理解

  • 自定义的命令类需要继承这个接口
  • 顾名思义,CanExecute方法就是查看命令能不能执行的
  • 顾名思义,Execute方法就是执行命令要进行的操作

下面进行自定义命令

在visual studio中直接继承并实现ICommand接口后会得到以下代码:

点击查看代码
    class MyCommand : ICommand
    {
        public event EventHandler? CanExecuteChanged;

        public bool CanExecute(object? parameter)
        {
            throw new NotImplementedException();
        }

        public void Execute(object? parameter)
        {
            throw new NotImplementedException();
        }
    }
  • 首先,不应该在定义命令的时候直接定死Execute执行的操作,所以在自定义的命令类中要声明一个Action,在实例化命令的时候指定Action,然后在Execute方法中调用Action。该部分的代码如下:
点击查看代码
        private Action? _TargetExecuteMethod;

        public void Execute(object? parameter)
        {
            //throw new NotImplementedException();
            if (_TargetExecuteMethod != null)
            {
                _TargetExecuteMethod();
            }
        }
  • 然后,CanExecute也不应该在定义命令类的时候直接定死,而是在声明命令的时候进行指定,所以在自定义命令类中要声明一个Func,在声明命令的时候对其进行赋值,在CanExecute中根据Func的情况进行判断命令是否可以执行。改部分代码如下:
点击查看代码
		private Func<bool>? _TargetCanExecuteMethod;

		public bool CanExecute(object? parameter)
        {
            if(this._TargetCanExecuteMethod!=null)
            {
                return _TargetCanExecuteMethod();
            }
            else
            {
                if(this._TargetExecuteMethod!=null)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
  • 然后,为自定义命令类添加构造函数,该部分代码如下:
点击查看代码
public MyCommand(Action? targetExecuteMethod, Func<bool>? targetCanExecuteMethod)
        {
            _TargetExecuteMethod = targetExecuteMethod;
            _TargetCanExecuteMethod = targetCanExecuteMethod;
        }
  • 至此,我们得到了一个比较完整的自定义命令类:
点击查看代码
class MyCommand : ICommand
    {
        public event EventHandler? CanExecuteChanged;

        public MyCommand(Action? targetExecuteMethod, Func<bool>? targetCanExecuteMethod)
        {
            _TargetExecuteMethod = targetExecuteMethod;
            _TargetCanExecuteMethod = targetCanExecuteMethod;
        }

        /// <summary>
        /// 传入的目标方法
        /// </summary>
        private Action? _TargetExecuteMethod;
        private Func<bool>? _TargetCanExecuteMethod;

        public bool CanExecute(object? parameter)
        {
            if(this._TargetCanExecuteMethod!=null)
            {
                return _TargetCanExecuteMethod();
            }
            else
            {
                if(this._TargetExecuteMethod!=null)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }

        public void Execute(object? parameter)
        {
            //throw new NotImplementedException();
            if (_TargetExecuteMethod != null)
            {
                _TargetExecuteMethod();
            }
        }
    }
  • Q:ICommand接口中还有一个CanExecuteChanged事件呢,怎么没说?A:因为我没学到,不会

有了自定义命令后,就可以使用了

  • 首先,在ViewModel中声明该属性,并进行赋值。
点击查看代码
        public MyCommand Command1 { get; set; }
		 public StudentViewModel()
        {
            studentmodel = new StudentModel();
            Command1 = new MyCommand(
            () =>
            {
                MessageBox.Show("this is a command");
            },

            () =>
            {
                return true;
            }
            );
        }
  • 然后在view中指定ViewModel为datacontext,并把按钮的命令绑定到ViewModel的属性上
点击查看代码
	<UserControl.DataContext>
        <viewmodel:StudentViewModel/>
    </UserControl.DataContext>
点击查看代码
        <Button Content="test"  Command="{Binding Path=Command1}"/>

运行结果

image

标签:ICommand,TargetExecuteMethod,MVVM,代码,object,命令,wpf,parameter,public
From: https://www.cnblogs.com/HamburgerX/p/17557160.html

相关文章

  • B站视频WPF实战教程修改代码
    P36HttpRestClient.cs部分代码publicasyncTask<ApiResponse>ExecuteAsync(BaseRequestbaseRequest){//urivaruri=newUri(apiUrl+baseRequest.Route);//newrestrequest//adduriv......
  • WPF - 001 数据绑定
    数据绑定WPF数据绑定四大要素:绑定源、绑定源属性、绑定目标、绑定目标属性。绑定源可以是:CLR对象ADOXMLDependencyObject绑定目标可以是:DependencyObject能够绑定的属性都是依赖属性,即DependencyProperty,所有DependencyProperty的值都是Object->Denpende......
  • WPF 实现 Message 消息提醒控件
    WPF实现Message消息提醒控件控件:Message作者:WPFDevelopersOrg-驚鏵原文链接:https://github.com/WPFDevelopersOrg/WPFDevelopers框架使用.NET4至.NET6;VisualStudio2022;接着上一篇1)新增MessageListBoxItem.cs代码如下:新增了名为MessageTy......
  • 深入浅出WPF——P91把子集集合的元素当Path
    publicpartialclassMainWindow:Window{publicMainWindow(){InitializeComponent();List<Country>countryList=newList<Country>(){newCountry......
  • WPF CheckBox勾选框大小设置
    1、设置CheckBox,FontSize,只有字体发生变化,前面的勾选框太小,可以设置LayoutTransform<StyleTargetType="CheckBox"><SetterProperty="HorizontalAlignment"Value="Left"/><SetterProperty="LayoutTra......
  • WPF TreeView 检测SelectedItem变化的简单方案
    TreeView无法绑定SelectedItem,而又想知道treeview的selecteditem的变化,当然目前有很多方法,我这里简单的提供一个。目前主要思路就是通过处理xaml的TreeViewItem的IsSelected属性来进行绑定。<TreeViewBorderThickness="0"Width="220"......
  • WPF获取MainWindows实例
    WPF获取MainWindow实例在其他类中获取MainWindow实例,获取其控件,改变其控件属性等,代码如下:_mainWindow=Application.Current.Windows.Cast<Window>().FirstOrDefault(Window=>WindowisMainWindow)asMainWindow;例如在ConfigureViewModel中改变MainWindow中的某个TextB......
  • WPF开发中ReactiveUI.Fody的使用
    前面的开发一般我会使用PropertyChanged.Fody,但ReactiveUI.Fody也能实现类似的功能。安装Nuget包Install-PackageReactiveUI.FodyFodyWeavers.xml文件:<Weaversxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"......
  • 管理员权限启动WPF应用程序
    1、添加应用程序清单文件 2、requestedExecutionLevel节点,level属性修改为“requireAdministrator”<requestedExecutionLevellevel="requireAdministrator"uiAccess="false"/> ......
  • WPF border解决超出圆角边界的方法
    使用Border并设置圆角,Border内部的其他元素会超出圆角而导致灾难级的视觉体验,通过设置Border的clip属性,来解决这个问题<BorderBorderThickness="1"BorderBrush="Black"CornerRadius="8"><Border.Clip>......