现在的位置: 首页 > 综合 > 正文

Silverlight-Caliburn应用框架4

2012年06月24日 ⁄ 综合 ⁄ 共 3343字 ⁄ 字号 评论关闭

         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

抱歉!评论已关闭.