开发一个Windows应用程序,肯定少不了控件的输入验证,而增加输入验证的方法不计其数,这里介绍一种使用Sophus的拦截功能来为你的  TextBox 控件很干净地增加输入验证的方法。“很干净”这里指的意思是可以透明的增加和删除输入验证而不用考虑任何用户逻辑代码。

现在我们有一个 TextBox 名为 textBox1 ,还有一个Button 叫 button1
这个button1有一个click事件,代码如下

     

private void button1_Click(object sender, System.EventArgs e)
         {
             MessageBox.Show("The number is \"" + textBox1.Text + "\"");
         }


如果我们要给 textBox1 控件增加一个输入验证,而不改动 button1 的代码要怎么办?

我们可以看一下 textBox1.Text这个属性,这个是一个virtual的属性,就意味着可以被拦截,好了,大致的解决办法出来了,我们是用 Sophus提供的 IInterceptor接口实现一个拦截器接口代码如下

public class NumberValidationInterceptor : IInterceptor
     {
         public object Intercept(IInvocation invocation, params object[] args)
         {
             string retString = invocation.Proceed(args) as string;            if(Regex.IsMatch(retString, @"^[+-]?\d*[.]?\d*$"))
             {
                 return retString;
             }
             else
             {
                 MessageBox.Show("Please input a number.","Validation Failure",MessageBoxButtons.OK, MessageBoxIcon.Warning);
                 return "0";
             }
         }
     }


这个拦截器具体要拦截什么,接下来我们定义一个Contract,里面就包含了拦截的具体对象和方法等详细信息,代码如下:
       

EmitProxyContract contract = new EmitProxyContract();
             contract.Target(typeof(TextBox));
             contract.Intercept(typeof(NumberValidationInterceptor), "get_Text");


然后呢就是创建这个动态代理的的类型
            EmitProxy proxy = (new EmitProxyFactory()).GetProxy(contract);
            proxy.Independent = true; 这里我们使用了 Independent = true 的意思就是可以将这个动态代理的配置与其他使用同样contract的动态代理配置独立出来,从而可以使用Sophus的一些高级功能,如下面这种
textBox1 = proxy.Wrap(this.textBox1) as TextBox;这句话就是使用由Sophus包装的textBox1类型动态替换掉原有的textBox1,而 textBox1的instance并没有变,大家可以看窗体上的控件就可以知道,但是上边的button1在click的时候就会被动态的hook住了,这就是Sophus的神奇之处。

看,当textBox1中输入的不是数字时,动态拦截器就生效了。

[AOP] 使用 Sophus 为 Windows 控件动态增加输入验证_windows

从这里下载Sophus免费版本: http://research.grapecity.com.cn/cs/files/7/sophus/default.aspx
Sophus论坛: http://research.grapecity.com.cn/cs/forums/14/ShowForum.aspx