Caliburn.Micro框架学习笔记——Action的参数传递机制

据此篇文章,我们继续来谈谈Caliburn.Mirco的Action参数传递机制。因此程序结构都是默认MVVM的形式。

基本机制

它的机制是——

Caliburn.Micro 的智能对象参数绑定机制通过约定和反射使得视图和视图模型之间的交互变得更加直观和简洁。通过 cal:Message.Attach 语法(附加属性的方法,其中cal是我们引入caliburn.mirco的命名空间的别名),你可以在 XAML 中定义事件处理,并且 Caliburn.Micro 会自动将参数传递给视图模型中的方法。

 那具体内部怎么实现的,我们这里不深究,而是去看怎么使用这个机制。但是其基本机制如下,个人总结,仅供参考。

  1. 命名约定:Caliburn.Micro 使用命名约定来匹配 XAML 中的事件处理和视图模型中的方法。

  2. 参数自动绑定:当事件被触发时,Caliburn.Micro 可以自动将事件参数传递给对应的视图模型方法。例如,按钮的 Click 事件可以将 RoutedEventArgs 传递给视图模型方法。

  3. Action 语法:使用 cal:Message.Attach 语法来明确指定事件和对应的视图模型方法。

 也就是说当我们想要触发事件并传入相应的参数时,在程序结构满足MVVM的情况下,我们有如下几种方法——

基本使用方法和步骤

在享受caliburn.micro给我们带来的便利之前,先来看看如果不使用它的机制的话,我们一般是怎么做的。

需要手动绑定控件的事件到代码后置文件中的事件处理程序,然后通过事件的形式的话,在后台cs代码中进行相应的逻辑书写。假设在视图层有以下代码

<Grid>
        <Button Name="MyButton" Content="Click Me" Width="100" Height="50" Click="MyButton_Click"/>
</Grid>

 在这里,这个button绑定了一个click事件,其事件名称为MyButton_Click。然后后台代码为——

private void MyButton_Click(object sender, RoutedEventArgs e)
{
    MessageBox.Show("Button clicked!");
}

那如果是使用MVVM的架构的话,这里一般是使用命令的形式来进行事件触发。因此视图层需要修改为,1,引入ViewModel,2,增加命令

<Window.DataContext>
   <local:MainViewModel />
</Window.DataContext>
<Grid>
   <Button Content="Click Me" Width="100" Height="50" Command="{Binding MyCommand}"/>
</Grid>

 然后相对应的ViewModel代码为

 public class MainViewModel
    {
        public ICommand MyCommand { get; }//命令

        public MainViewModel()
        {
            MyCommand = new RelayCommand(ExecuteMyCommand);//利用RelayCommand进行命令绑定
        }

        private void ExecuteMyCommand(object parameter)//命令的要执行的逻辑
        {
            MessageBox.Show("Button clicked!");
        }
    }

    public class RelayCommand : ICommand//这个命令继承自ICommand,并实现
    {
        private readonly Action<object> _execute;
        private readonly Func<object, bool> _canExecute;

        public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
        {
            _execute = execute;
            _canExecute = canExecute;
        }

        public event EventHandler CanExecuteChanged
        {
            add => CommandManager.RequerySuggested += value;
            remove => CommandManager.RequerySuggested -= value;
        }

        public bool CanExecute(object parameter)//命令执行判断
        {
            return _canExecute == null || _canExecute(parameter);
        }

        public void Execute(object parameter)//带参数传递到命令要去执行
        {
            _execute(parameter);
        }
    }

 天啊,感觉看到以上内容,感觉头大。于是当引入caliburn.Micro后,我们看看效果。

但是使用之前来了解其约定和机制:

  1. 控件命名约定

    • 在视图中,控件命名应该遵循一定的约定。例如,一个按钮的名称可以包含事件名称和方法名称的组合。
  2. 视图模型方法命名

    • 在视图模型中,方法的命名应该与控件的名称相对应。

其基本机制是

  1. 命名约定:Caliburn.Micro 使用命名约定来匹配 XAML 中的事件处理和视图模型中的方法。例如,按钮的 Click 事件可以自动映射到视图模型中的 ButtonName_Click 方法。

  2. 参数自动绑定:当事件被触发时,Caliburn.Micro 可以自动将事件参数传递给对应的视图模型方法。例如,按钮的 Click 事件可以将 RoutedEventArgs 传递给视图模型方法。

  3. Action 语法:使用 cal:Message.Attach 语法来明确指定事件和对应的视图模型方法。

 它的原理是——

Caliburn.Micro 使用反射和约定来绑定视图中的控件事件和视图模型中的方法。以下是这个过程的基本原理:

  1. 查找控件

    • Caliburn.Micro 在视图中查找所有控件,并读取它们的 Name 属性。
  2. 解析事件和方法

    • 根据控件的 Name 属性,Caliburn.Micro 解析出控件类型(如 Button)和事件名称(如 Click)。
  3. 查找方法

    • 在视图模型中查找与事件名称对应的方法。在这个示例中,Caliburn.Micro 查找一个名为 ButtonClick 的方法。
  4. 绑定事件

    • 使用反射将控件的事件(如按钮的 Click 事件)绑定到视图模型中的方法。
  5. 触发方法

    • 当控件的事件被触发时,Caliburn.Micro 调用视图模型中的相应方法。

 所以当引入了这个类库之后,我们有如下方便的操作。

1)直接写一个空间Name让它自动去mvvm中匹配对应的方法名

在视图层

<Button Content="Button" Name="ButtonTest"/>

在MVVM中

  public void ButtonTest()
  {
      Value++;//视图中的某个参数
  }

那么他会去匹配到ButtonTest这个方法。我们断点调试就可以看到它直接到这里。是不是很爽。

传参机制

2)当我们想要传入参数时,可以怎么做?它具备怎样的规则?

参数匹配规则

  1. 事件参数:如果方法有一个参数,Caliburn.Micro 会尝试将事件参数(如 RoutedEventArgs)传递给方法。
  2. 属性名匹配:如果方法有多个参数,Caliburn.Micro 会尝试通过反射来匹配方法参数的名称和类型。
  3. 默认值和类型匹配:如果找不到确切匹配的参数,框架会尝试使用默认值或进行类型转换,以满足方法签名。

一)使用Caliburn.micro的ActionMessage

 <Button Content="测试">
     <i:Interaction.Triggers>
         <!--使用的是xmlns:i="http://schemas.microsoft.com/xaml/behaviors"中关于行为触发的机制,需要触发的是Click事件-->
         <i:EventTrigger EventName="Click">
             <cm:ActionMessage MethodName="EventAction">
                 <!--告知这个click事件一旦点击就会触发,且对应的是ViewModel中的方法EventAction-->
                 <cm:Parameter Value="1"/><!--这里就是告知这个事件触发之后会传入的参数-->
                 <cm:Parameter Value="2"/>
                 <cm:Parameter Value="3"/>
             </cm:ActionMessage>
         </i:EventTrigger>
     </i:Interaction.Triggers>
 </Button>

那么在ViewModel中,我们可以有对应的EventAction方法

  public void EventAction(int aa, int bb, int cc)
  {

  }

当点击这个按钮时,断点调试会跳到这里,那我们可以根据需要进行逻辑的书写。

同理,当我们的参数没写时,是否会自动匹配?

 <TextBox Text="12" Name="aaa"/>
 <Button Content="智能对象参数绑定-命令" Name="AAAAction"/>

 此时,当有一个方法名字为AAAAction,它的参数会传入aaa,且此时它的传入参数命名也为aaa。

二)使用智能语法匹配

使用的是附加属性的逻辑。

  <Button Content="基本智能语法-命令"
          cm:Message.Attach="[Event Click] = [Action EventAction(1,2,tb.Text)]"/>

 其中

  1. cm:Message.Attach是 Caliburn.Micro 提供的附加属性,用于将视图中的事件绑定到视图模型中的方法。

    • [Event Click] 指定了按钮的 Click 事件。
    • [Action ButtonClick(1,2,tb.Text)] 指定了视图模型中的 ButtonClick 方法,并传递 Click 事件的参数。

此时可以看到,我们可以很好滴直接传入view中的某个控件的属性作为参数。但是当我们不明确指出它的参数的时候,是否可以?这就有另外一个机制,就是占位符。

三)使用占位符的形式传参

我总结如下

  1. $eventArgs:这是一个占位符,表示事件参数。Caliburn.Micro 会自动将 Click 事件的 RoutedEventArgs 传递给 ButtonClick 方法。

  2. $dataContext:这是一个特殊的占位符,表示按钮所在的上下文(DataContext)。在 MVVM 模式中,DataContext 通常是绑定到视图的视图模型。[Event Click] = [Action EventAction($dataContext)]:这段语法表示当按钮的 Click 事件触发时,调用视图模型中的 EventAction 方法,并将 DataContext 作为参数传递给该方法。在这个示例中,当你点击按钮时,EventAction 方法会被调用,并且 dataContext 参数会被传递给它。在 EventAction 方法中,dataContext 参数就是视图模型的实例本身(MainViewModel
  3. $view:在这里,$view 占位符表示触发事件的视图元素本身。在这个例子中,视图元素是按钮。
  4. $this:在这里,$this 占位符表示当前视图的实例本身。在视图模型中,参数类型应该与视图类型匹配,以便接收视图的实例

其使用分别为——

  <Button Content="$eventArgs参数-命令"
          cm:Message.Attach="[Event Click] = [Action EventAction($eventArgs)]"/>
  <Button Content="$dataContext参数-命令"
          cm:Message.Attach="[Event Click] = [Action EventAction($dataContext)]"/>
  <Button Content="$view参数-命令"
          cm:Message.Attach="[Event Click] = [Action EventAction($view)]"/>
  <Button Content="$this参数-命令"
          cm:Message.Attach="[Event Click] = [Action EventAction($this)]"/>

 然后我们ViewModel层的方法有

 public void EventAction(object arg)
 {

 }

此时我们可以断点到这个方法,然后去看这个arg,我们就可以很清楚的知道,当前它传入的参数是什么。可以很清楚的知道参数类型。

这几个方法的使用心得——》

  • $dataContext:用于将数据上下文(通常是视图模型实例)作为参数传递给方法。
  • $eventArgs:用于将事件参数作为参数传递给方法。
  • $view:用于将触发事件的视图元素本身作为参数传递给方法。

选择使用 $dataContext$eventArgs$view 取决于你需要在事件处理方法中处理的数据。如果你需要访问视图模型实例,使用 $dataContext;如果你需要处理事件参数,使用 $eventArgs;如果你需要访问触发事件的视图元素,使用 $view

使用 $this

  • 可以将当前视图的实例传递给视图模型方法。
  • 方便在视图模型中直接访问当前视图的属性和方法。
  • 适用于需要在视图模型中直接操作视图的情况。

但需要注意,使用 $this 会引入视图模型对视图的直接依赖,可能会破坏 MVVM 架构的一些原则,因此应该谨慎使用。

  • 41
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
WPF(Windows Presentation Foundation)是一种用于创建Windows桌面应用程序的用户界面框架,而Caliburn.Micro是一种针对WPF应用程序的轻量级MVVM框架。通过结合使用这两个框架,可以更高效地编写WPF应用程序的界面和逻辑部分。 一个基本的WPF Caliburn.Micro框架编写案例可以是一个简单的待办事项列表应用程序。首先,我们可以创建一个WPF应用程序,并添加Caliburn.Micro框架的引用。然后,我们可以定义待办事项的模型,包括待办事项的名称、描述和状态等属性。 接下来,我们可以使用Caliburn.Micro框架提供的ViewModelBase类来创建一个待办事项的视图模型。在视图模型中,我们可以定义与界面交互的属性和命令,比如显示待办事项列表、添加新的待办事项、标记已完成的待办事项等功能。 然后,我们需要创建一个WPF的视图,用于显示待办事项列表和与用户进行交互。在视图中,我们可以绑定视图模型中的属性和命令,并使用WPF的控件来显示和编辑待办事项。 最后,我们将视图模型绑定到视图上,使得视图与视图模型能够实现双向的数据绑定和命令绑定。这样,当用户在界面上进行操作时,视图和视图模型之间的数据和行为可以实现同步。 通过这样一个简单的案例,我们可以看到WPF Caliburn.Micro框架编写的优势,它能够帮助我们更快速和高效地构建WPF应用程序,并实现良好的界面和逻辑分离。同时,借助MVVM架构,我们也能够实现更好的代码可读性和可维护性。 WPF Caliburn.Micro框架编写案例的实践将有助于我们更好地理解和运用这些框架,提升WPF应用程序的开发效率和质量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Matrix Y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值