WPF Caliburn 学习笔记(一) Action

前言:

这些内容都是在Caliburn 1.1版本基础上,学习的心得。其中有些不懂的地方或写错的地方请大家指正。

基础

在配置Caliburn时,我们先要添加3个引用,分别是:

  1. Caliburn.Core.dll
  2. Caliburn.PresentationFramework.dll
  3. Microsoft.Practices.ServiceLocation.dll

Caliburn不止这两个引用,要用到的时候,再提出。

要想使用Caliburn来写事件,首先要在App.xaml.cs中配置它。

打开App.xaml.cs

 public App()
        {
            CaliburnFramework.ConfigureCore().WithPresentationFramework().Start();
        }
别忘了下面面两个引用。 后面的类中都要用到

using Caliburn.Core;
using Caliburn.PresentationFramework;

这里的App构造函数里写的,是Caliburn容器的配置。要用Caliburn的Action就要这么写,具体为什么这么配置。

不太清楚。希望高人指教。

接下来我们可以在界面上操作了。我们新建一个Calculator.cs类,这个类用来写Action事件的。

我们在MainWindow.xaml中放上两个TextBox,三个TextBlock和一个Button,Button的Click的事件用Caliburn来写。

别忘了添加 xmlns:cal="http://www.caliburnproject.org"这个引用。

<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="32*" />
            <RowDefinition Height="279*" />
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal" >
            <TextBox x:Name="left" Width="150" />
            <TextBlock Margin="5 0"> /</TextBlock>
            <TextBox x:Name="right" Width="150"/>
            <TextBlock Margin="5 0"> =</TextBlock>
            <TextBlock x:Name="result" Width="150"/>
        </StackPanel>
        <StackPanel Grid.Row="1" >
            <Button Content="Divide"  cal:Message.Attach="Divide"/>
        </StackPanel>
    </Grid>

我们在Calculator.cs类中写Divide处理的事件函数。

  public int Divide(int left,int right)
       {
           return left / right;
       }
按F5运行,你会看到如下的错误:

There was no handler found for the message Action: Divide.

意思是:没有找到相应的处理事件,也就是没找到这里的 Divide(int left,int right)函数。

我们想想为什么没有找到。这里我们的MainWindow.xaml页面和Calculator.cs类关联起来了吗?

答案:显然没有。

在MainWindow.xaml中的添加

<cal:Action.Target>
       <local:Calculator/>
   </cal:Action.Target>

这里的local是xaml对本地的引用如:xmlns:local="clr-namespace:Action"

现在运行不会报错了,但是没结果,因为我们写的事件返回的是一个int型的数据,这个数据让谁显示呢?

界面上没有指定。所以我们修改cal:Message.Attach="Divide"的写法,因为刚才的写法只适合没有参数传入和传出的情况。

而这里要传入两个参数,并返回一个int型的数据。

修改为:

方法一:

cal:Message.Attach="Divide(left.Text,right.Text):result.Text"
这里的left,right,result是控件的Name.
运行成功了。附图:
image

为什么我们点击了 就执行它了呢,而不是鼠标移到上去的时候执行了这个事件。

我们把它写的跟全一点就是:

方法二:

cal:Message.Attach="[Event Click]=[Action Divide(left.Text,right.Text):result.Text]"

这里默认是Click事件。现在想用什么事件,都可以了。这么简洁的代码具体怎么来的呢?

方法三:

<Button Content="Divide (2)" >
     <cal:Message.Triggers>
           <cal:RoutedMessageTriggerCollection>
               <cal:EventMessageTrigger EventName="Click">
                   <cal:EventMessageTrigger.Message>
                        <cal:ActionMessage MethodName="Divide" OutcomePath="result.Text">
                             <cal:Parameter Value="{Binding ElementName=left, Path=Text}"/>
                            <cal:Parameter Value="{Binding ElementName=right, Path=Text}"/>
                       </cal:ActionMessage>
                  </cal:EventMessageTrigger.Message>
             </cal:EventMessageTrigger>
         </cal:RoutedMessageTriggerCollection>
     </cal:Message.Triggers>
</Button>

延伸一:

我们知道绑定中有4中绑定方式,比如:双向绑定(TwoWay),方法三中很好写,那么我们如何在方法二中写呢?

答案如下:

cal:Message.Attach="[Event Click]=[Action Divide(left.Text:TwoWay,right.Text:OneWay):result.Text]"
在后面加“:”加上你要的绑定方式就可以了。
继续思考,我们要在Button里有多个事件怎么办呢?比如有MouseEnter事件的时候。
<Button Content="Divide"  
cal:Message.Attach="[Event Click]=[Action Divide(left.Text:TwoWay,right.Text:OneWay):result.Text];
                    [Event MouseEnter]=[Action Message]"/>
答案是:加“;”后面可以加多个事件了。

延伸二:

需求一直在变化,我们知道做除法的时候,分母不能为0的,可是上面的没做处理。我们在第二个TextBox中输入0的话,

报错了哦~~

我们在上面加个判断吧。

       [Preview("CanDivide")]
       public int Divide(int left,int right)
       {
           return left / right;
       }

       public bool CanDivide(int left,int right)
       {
           return right != 0;
       }

运行结果:

开始:

image
输入后:

image
输入0,不能点哦。

输入其他数字:

image

可点可执行。

在函数上加[Preview("CanDivide")] ,说明执行函数前,会去执行CanDivide 这个函数。

假如函数名前加Can,Caliburn默认会先执行它。也就是说有了CanDivide,Divide上面不必加[Preview("CanDivide")] 了,

Caliburn默认会自动调用。

总结遗留的问题:

在App.xaml.cs中为什么要加

  1. CaliburnFramework.ConfigureCore().WithPresentationFramework().Start(); 它是怎么来的。如果有弹出窗体,要不要用IOC注入呢?
  2. <cal:Action.Target>
    <local:Calculator/>
    </cal:Action.Target>

        我们引用后台的方法,为什么要这样引用,如果在MVVM模式下,要不要这样用呢?

希望大家指点。谢谢。

代码:

https://files.cnblogs.com/dingli/WPFCalliburn.rar

posted @ 2011-03-08 17:20  Lee's Blog  阅读(6215)  评论(3编辑  收藏  举报