zoukankan      html  css  js  c++  java
  • SilverlightCaliburn应用框架4

             Silverlight-Caliburn应用框架1

             Silverlight-Caliburn应用框架2

             Silverlight-Caliburn应用框架3

             Silverlight-Caliburn应用框架4 

             Silverlight-Caliburn应用框架5

             Silverlight-Caliburn应用框架6

         上一篇了解了简单的Action特性,这篇我们关注Action其它的一些使用场景。

            前面的例子是求一个数的平方根,因为我们这里没有对输入进行任何处理,所以当我们输入一个非正数时,Sqrt函数会返回NaN

                      1

           一般而言,我们可以通过抛出异常的方式进行处理,但是更为友好的方式是在用户输入数值时就进行处理,这里我们就用到了Caliburn的Filter特性,其包含

    了PreView,Rescue,以及AsyncAction这3个过滤器,也可以自己定义,下面我们在前面的例子基础上了解其过虑器的使用。

          在Extraction类中添加一个PreView过滤器,看看修改过后的类

           using Caliburn.PresentationFramework.Filters;
    
           public class Extraction
    
           {
    
            [Preview("IsValueCanExtrace",AffectsTriggers=true)]
    
            public double Extrace(double param)
    
            {
    
                return Math.Sqrt(param);
    
            }
    
            public bool IsValueCanExtrace(double param)
    
            {
    
                return param >= 0;
    
            }
    
           }

          这里我们定义了一个IsValueCanExtrace()验证输入参数的有效性,PreView过滤器指定了IsValueCanExtrace方法,其将在Extrace()执行前执行,

    AffectsTriggers默认值是True,使用True值可以使得这个过滤器影响到UI上控件的状态,我们看看效果图:

            12    

                                   13

           当我们在文本框中输入-7时,Button会自动被禁用,输入7时,验证可以通过,这种方式比抛出异常进行处理更为友好。

          在Caliburn中,关于过滤器有一个命名规范,如果你使用Can{MethodName}这种命名方式,它将自动的将过滤器对应到该方法中,所以上面的代

    码我们可以写成这种方式:

            public class Extraction
    
           {       
    
            public double Extrace(double param)
    
            {
    
                return Math.Sqrt(param);
    
            }
    
            public bool CanExtrace(double param)
    
            {
    
                return param >= 0;
    
            }      
    
           }

          运行之后两者的效果是一样的,也可以把Can{MethodName}定义成属性,它也会被自动触发,所以只有你的命名是另外的方式时才需要用PreView特

    性。关于过滤器的功能还有很多,不过这个足以应付一般的操作了,现在我们再来看一看Action的异步操作。

          异步操作则用到了AsyncAction过滤器,我们进一步修改代码

           using Caliburn.PresentationFramework.Actions;
    
           public class Extraction
    
           {
    
            [AsyncAction(BlockInteraction = true)]
    
            public double Extrace(double param)
    
            {
    
                System.Threading.Thread.Sleep(2000);
    
                return Math.Sqrt(param);
    
            }
    
            public bool CanExtrace(double param)
    
            {
    
                return param >= 0;
    
            }     
    
          }

          当Button处于异步操作时,其状态将变为Disable,UI的其它部分仍然可以进行响应,当操作完成时,会将结果输出在文本框中,同时Button状态

    会自动变为Enable,这里就是AsyncAction所起的作用,当方法被其修饰时,即表示需要在后台执行,同时将BlockInteraction设为True时,可以控

    制源(这里即Button)在异步操作完成前被禁用。

           我们也可以在异步方法中指定回调函数,看下其实现:

            [AsyncAction(Callback = "ExtraceComplate",BlockInteraction = true)]
    
            public double Extrace(double param)
    
            {
    
                System.Threading.Thread.Sleep(2000);
    
                return Math.Sqrt(param);
    
            }
    
            public double ExtraceComplate(double result)
    
            {
    
               return result * 1000;
    
            }
    

           代码中在AsyncAction特性中指定了一个Callback函数,Caliburn会自动在UI线程上将异步执行的结果作为参数传递给Callback函数,如果回调函数有

    返回值,则将最终结果绑定到UI上               14

            关于Rescue过滤器就不细说明了,其可以通过修饰类或方法指向一个未处理的异常,其实这也是我倾向于使用PreView的原因,最后我们再关注一下依赖行为,依赖行为是在前面的标准行为机制基础上增加的一个特性,它可以让Caliburn知道类的方法的执行需要依赖于哪一个属性,我们通过修改Extraction来理解这句话

           public class Extraction:INotifyPropertyChanged
    
           {
    
            [Dependencies("Param")]
    
            public void  Extrace()
    
            {
    
                Result = Math.Sqrt(Param);
    
            }  
    
            public bool CanExtrace()
    
            {   
    
                return Param>=0;
    
            }
    
            public double _prarm;
    
            public double Param
    
            {
    
                get 
    
                {             
    
                    return _prarm;
    
                }
    
                set {
    
                    _prarm = value;
    
                    if (PropertyChanged != null)
    
                    {
    
                        this.PropertyChanged(this, new PropertyChangedEventArgs("Param"));
    
                    }
    
                }
    
            }
    
            public double _result;
    
            public double Result
    
            {
    
                get 
    
                {
    
                    return _result;
    
                }
    
                set {
    
                   _result = value;
    
                    if (PropertyChanged != null)
    
                    {
    
                        this.PropertyChanged(this, new PropertyChangedEventArgs("Result"));
    
                    }
    
                }
    
            }
    
            public event PropertyChangedEventHandler PropertyChanged;

          这个时候与我们之前的类结构已经大不相同了,在这种方式下,我们不需要再将参数传给Extrace(),因为ViewModel将通过属性的变化维护其所需要的值,

    并通过DependenciesAttribute指定了Extrace()所依赖的属性

         现在我们看一看UI:

            <TextBox  Text="{Binding Param,Mode=TwoWay}" />
    
            <TextBox  Text="{Binding Result,Mode=TwoWay}"/>  
    
            <Button Content="计算" pf:Message.Attach="Extrace" ></Button>

          我们将Param属性绑定到输入框,将Result绑定到结果,这种方式是我们在MVVM中熟悉的绑定方式,运行之后所看的效果和我们前面所做的是一样的,

    Action部分功能比较丰富,我想即使只掌握了上面这几点,也是可以应付大多数情况的。

        

        代码下载:DependentAction  环境:VS2010+SL3

  • 相关阅读:
    WPF Prefix 'attach' does not map to a namespace.
    C# 用ManulResetEvent 控制Thread的 Suspend、Resume
    C# 监控Windows睡眠与恢复
    c# DataTable to Object Mapping
    C# DispatcherTimer Start之后立即执行
    Visual studio 编译时copy文件、文件夹
    c# 无法加载xxx.dll 找不到指定的模块(如何指定文件夹)
    EntityFramework 找不到方法:“Void System.Data.Entity.DbModelBuilder.RegisterEntityType
    wpf 全局异常捕获处理
    pandas入门
  • 原文地址:https://www.cnblogs.com/626498301/p/1808299.html
Copyright © 2011-2022 走看看