MVVM的目的是为了最大限度地降低了Xaml文件和CS文件的合度,分离界面和业务逻辑,所以我们要尽可能的在View后台不写代码。
但是这个例子中,我们将更新ViewModel的代码写在了View里。我们能否把按钮的响应处理代码也不写在后台代码里呢? WPF引入Command(命令),通过为Button设置Command来做响应: 命令:Command是一种不同于输入设备的语义级别上的入处理机制 Command的目的:1)降低代码耦合度,将Command的逻辑和调用对象进行分离2)可以指定对象是否可用;Command允许多个不同的对象可以调用同一个命令,也可以为不同的对象定义特殊的逻辑;
命令分类: 1.预定义的命令(predefined command)
1)ApplicationCommands 提供一组与应用程序相关的标准命令(可以直接使用
2)ComponentCommands 提供一组标准的与组件相关的命令
3)Navigationcommands,提供一-组标准的与导航相关的命令
还有很多诸如:MediaCommands,EditingCommands 2.自定义Command (1)command:要执行的操作。 所有的命令需要继承自接口ICommand. Execute:执行与命令关联的操作, CanExecute:决定对于当前目标command能否被执行。 CanExecuteChanged(事件):当出现影响是否应执行该命令的更改时发生
public class RelayCommand : ICommand { public event EventHandler CanExecuteChanged; private Action<object> executeActions; private Func<object, bool> canExecuteFunc; public RelayCommand() { } public RelayCommand(Action<object> execute) : this(execute, null) { } public RelayCommand(Action<object> execute, Func<object, bool> canExecute) { this.executeActions = execute; this.canExecuteFunc = canExecute; } public bool CanExecute(object parameter) { if (canExecuteFunc != null) return this.canExecuteFunc(parameter); else return true; } public void Execute(object parameter) { if (executeActions == null) return; this.executeActions(parameter); } public void OnCanExecutechanged() { this.CanExecuteChanged?.Invoke(this, new EventArgs()); } }
二、建立业务类 MainViewModel类 public class MainViewModel { //先实例化这个命令(这是属于ViewModel的命令,等下要被送到View中去) public RelayCommand MyCom { get; set; }public MainViewModel() { //在ViewModel的构造函数中,完成对命令的设置 MyCom = new RelayCommand(); MyCom.canExecuteFunc = new Func<object, bool>(this.CanDoSomething);//命令执行先进行判断,这里和MyCommand中的CanExecute都可以进行判断。 MyCom.executeActions = new Action<object>(this.DoSomething);//执行命令,带一个参数 //MyCom.ExecuteAction0 = new Action(this.DoSomething0);//执行命令,不带参数 } public void DoSomething(object param) { MessageBox.Show("123" + param);//执行方法,返回界面的命令带的参数 } public void DoSomething0() { MessageBox.Show("123");//执行方法,返回界面的命令带的参数 } public bool CanDoSomething(object param) { //这里可以和界面进行数据交互,进行判断。判断能否做这个事情,大部分时候返回true就行了,返回false,方法就不执行了。 return true; } }
3.在MainWindow中关联上MainViewModel。 public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); this.DataContext = new MainViewModel(); } }
<Window x:Class="WpfApp1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp1" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid> <Button Content="Button" HorizontalAlignment="Left" Margin="222,185,0,0" Command="{Binding MyCom}" CommandParameter="{Binding ElementName=txt, Path=Text}" VerticalAlignment="Top" Width="75"/> <TextBox x:Name="txt" HorizontalAlignment="Left" Height="23" Margin="222,128,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/> </Grid> </Window>
上面是传递单个值,下面说说多值传递的问题,传值有2种方法 第一种,建立一个对象,把对象当做整体传入 首先建立stu类
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public int Gender { get; set; }
public double Left { get; set; }
public double Top { get; set; }
}
public class MainViewModel { //先实例化这个命令(这是属于ViewModel的命令,等下要被送到View中去) public RelayCommand MyCom { get; set; } public Person person { get; set; } public MainViewModel() { //在ViewModel的构造函数中,完成对命令的设置 MyCom = new RelayCommand(); MyCom.canExecuteFunc = new Func<object, bool>(this.CanDoSomething);//命令执行先进行判断,这里和MyCommand中的CanExecute都可以进行判断。 MyCom.executeActions = new Action<object>(this.DoSomething);//执行命令,带一个参数 //MyCom.ExecuteAction0 = new Action(this.DoSomething0);//执行命令,不带参数 person = new Person() { Name = "aaa", Age = 3 }; } public void DoSomething(object param) { MessageBox.Show("123" + param);//执行方法,返回界面的命令带的参数 } public void DoSomething0() { MessageBox.Show("123");//执行方法,返回界面的命令带的参数 } public bool CanDoSomething(object param) { //这里可以和界面进行数据交互,进行判断。判断能否做这个事情,大部分时候返回true就行了,返回false,方法就不执行了。 return true; } }
第二种,使用多参数的方式传值
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Data; namespace WpfApp1 { public class ObjectConvert : IMultiValueConverter { #region IMultiValueConverter Members public static object ConverterObject; public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return values.ToArray(); } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } #endregion } }
<Window x:Class="WpfApp1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp1" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Window.Resources> <local:ObjectConvert x:Key="objectConverter"></local:ObjectConvert> </Window.Resources> <Grid> <!--<Button Content="Button" HorizontalAlignment="Left" Margin="222,185,0,0" Command="{Binding MyCom}" CommandParameter="{Binding ElementName=txt, Path=Text}" VerticalAlignment="Top" Width="75"/>--> <!--<Button Content="Button" HorizontalAlignment="Left" Margin="222,185,0,0" Command="{Binding MyCom}" CommandParameter="{Binding a}" VerticalAlignment="Top" Width="75"/>--> <Button Content="Button" HorizontalAlignment="Left" Margin="222,185,0,0" Command="{Binding MyCom}" VerticalAlignment="Top" Width="75"> <Button.CommandParameter> <MultiBinding Converter="{ StaticResource ResourceKey=objectConverter}"> <Binding ElementName="txt"></Binding><!--传整个控件--> <Binding ElementName="txt_Copy" Path="Text"></Binding><!--传控件的值--> <Binding Path="a" ></Binding><!--传对象--> <Binding Source="自定义值" ></Binding> <!--传自定义的值--> </MultiBinding> </Button.CommandParameter> </Button> <TextBox x:Name="txt" HorizontalAlignment="Left" Height="23" Margin="222,128,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/> <TextBox x:Name="txt_Copy" HorizontalAlignment="Left" Height="23" Margin="412,172,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/> </Grid> </Window>
来源:https://blog.csdn.net/u012563853/article/details/124892976
标签:MyCom,object,命令,Command,new,WPF,public From: https://www.cnblogs.com/ywtssydm/p/18362435