SilverLight学习笔记--实际应用(一)(5):手把手建立一个Silverlight应用程序之异步数据校验2...

上一节我们学习如何在客户端进行同步数据校验,但在许多时候,我们需要把输入的数据与后台数据库中的数据进行校验,即把校验工作放到服务器端完成,然后把校验结果返回到客户端。
  本篇文章主要演示:
  1、如何利用WCF在服务器端进行数据校验。
  2、如何制作一个异步等待数据校验的等待提示界面。
 
一、如何利用WCF在服务器端进行数据校验。
 1、服务器端利用WCF完成数据校验功能
 在SLApplicationDataTest.Web项目上"添加"--"新建项",新建一个"启用Silverlight的WCF服务",服务名命名为:SexWCF.svc,如下图:
                        
 编写SexWCF.svc.cs代码如下:
using  System;
using  System.Linq;
using  System.Runtime.Serialization;
using  System.ServiceModel;
using  System.ServiceModel.Activation;
using  System.Collections.Generic;
using  System.Text;

namespace  SLApplicationDataTest.Web
ExpandedBlockStart.gifContractedBlock.gif
{
    [ServiceContract(Namespace 
= "")]
    [AspNetCompatibilityRequirements(RequirementsMode 
= AspNetCompatibilityRequirementsMode.Allowed)]
    
public class SexWCF
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        [OperationContract]
ContractedSubBlock.gifExpandedSubBlockStart.gif        
服务器端数据校验,返回结果为bool值#region 服务器端数据校验,返回结果为bool值
        
public bool  SexValidation(string SexStr)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
//延时处理,是为了后面我们在演示“等待校验提示窗口”时能有足够的时间看到提示窗口
            System.Threading.Thread.Sleep(1000);


ContractedSubBlock.gifExpandedSubBlockStart.gif            
在此处添加服务器端的数据校验代码#region 在此处添加服务器端的数据校验代码
            
//此处,如果输入的性别是Male或Female则合法
            return ("Male"==SexStr||"Female"==SexStr);
            
#endregion


        }

        
#endregion




        
// 在此处添加更多操作并使用 [OperationContract] 标记它们
    }

}

2、在客户端引用WCF数据校验服务
 在SLApplicationDataTest项目上添加服务引用,如下图:
                        
成功引入服务器端WCF服务后,我们需要修改Person类代码,在其中加入如下代码:
   #region   性别输入校验程序:通过调用WCF服务来完成校验工作
        
private   void  ValidateSex( string  SexStr)
        {
            SexWCFClient sexCs 
=   new  SexWCFClient();
            sexCs.SexValidationCompleted 
+=   new  EventHandler < SexValidationCompletedEventArgs > (sexCs_SexValidationCompleted);
            sexCs.SexValidationAsync(SexStr, SexStr);  
// 其中第二个SexStr为传入的UserState参数,将在sexCs_SexValidationCompleted中使用
        }

        
public   void  sexCs_SexValidationCompleted( object  sender, SexValidationCompletedEventArgs e)
        {
            
if  ( ! e.Result)
            {
                HtmlPage.Window.Alert(e.UserState.ToString() 
+   "  无效,请重新输入! " ); // 其中e.UserState是SexValidationAsync方法中的第二个传参
            }
        }

        
#endregion

这段代码使用了WCF数据校验服务来完成对SexStr的数据校验。
 另外,我们需要修改Sex属性的Set段,如下:

         public   string  Sex
        {
            
get  {  return  _sex; }
            
set
            {
                
if  (value  ==  _sex)  return ;
                _sex 
=  value;
                OnPropertyChanged(
" Sex " );
                ValidateSex(_sex); 
// 调用WCF服务来进行数据校验
            }
        }

Person类全部代码如下:

using  System;
using  System.Net;
using  System.Windows;
using  System.Windows.Controls;
using  System.Windows.Documents;
using  System.Windows.Ink;
using  System.Windows.Input;
using  System.Windows.Media;
using  System.Windows.Media.Animation;
using  System.Windows.Shapes;
using  System.ComponentModel;  // 因为要用到INotifyPropertyChanged接口
using  SLApplicationDataTest.SexServiceReference;  // 因为要使用WCF服务
using  System.Windows.Browser;  // 因为要使用HtmlPage.Window.Alert


namespace  SLApplicationDataTest
ExpandedBlockStart.gifContractedBlock.gif
{
    
public class Person : INotifyPropertyChanged
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
private string _name;
        
private string _sex;
        
private int _age;
        
private string _address;

ContractedSubBlock.gifExpandedSubBlockStart.gif        
Constructors#region Constructors
ExpandedSubBlockStart.gifContractedSubBlock.gif        
public Person() { }

        
public Person(string NameStr, string SexStr, int AgeInt, string AddressStr)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
this._name = NameStr;
            
this._sex = SexStr;
            
this._age = AgeInt;
            
this._address = AddressStr;
        }

        
#endregion



ContractedSubBlock.gifExpandedSubBlockStart.gif        
Properties#region Properties

        
public string Name
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return _name; }
            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (value == _name) return;
                _name 
= value;
                OnPropertyChanged(
"Name");
            }

        }


        
public string Sex
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return _sex; }
            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (value == _sex) return;
                _sex 
= value;
                OnPropertyChanged(
"Sex");
                ValidateSex(_sex); 
//调用WCF服务来进行数据校验
            }

        }


        
public int Age
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return _age; }
            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (value == _age) return;

                 
//如果输入的不是整数,则抛出异常
                try
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    Convert.ToInt32(value);
                }

                
catch(Exception ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
throw new Exception(ex.ToString());
                }

                 
                
//如果输入的整数不在合理范围同,则也抛出异常

                
if (value < 0 || value > 200)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
throw new Exception("Age must be between 0 and 200");
                }



                _age 
= value;
                OnPropertyChanged(
"Age");
            }

        }


        
public string Address
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return _address; }
            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (value == _address) return;
                _address 
= value;
                OnPropertyChanged(
"Address");
            }

        }

        
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif        
INotifyPropertyChanged 接口实现#region INotifyPropertyChanged 接口实现
        
public event PropertyChangedEventHandler PropertyChanged;

        
protected void OnPropertyChanged(string name)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (PropertyChanged != null)
                PropertyChanged(
thisnew PropertyChangedEventArgs(name));
        }

        
#endregion



ContractedSubBlock.gifExpandedSubBlockStart.gif        
性别输入校验程序:通过调用WCF服务来完成校验工作#region  性别输入校验程序:通过调用WCF服务来完成校验工作
        
private void ValidateSex(string SexStr)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            SexWCFClient sexCs 
= new SexWCFClient();
            sexCs.SexValidationCompleted 
+= new EventHandler<SexValidationCompletedEventArgs>(sexCs_SexValidationCompleted);
            ((Page)Application.Current.RootVisual).StartWait(
"请稍候,正在校验性别输入!");
            sexCs.SexValidationAsync(SexStr, SexStr);  
//其中第二个SexStr为传入的UserState参数,将在sexCs_SexValidationCompleted中使用
        }


        
public void sexCs_SexValidationCompleted(object sender, SexValidationCompletedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            ((Page)Application.Current.RootVisual).EndWait(
null);
            
if (!e.Result)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                HtmlPage.Window.Alert(e.UserState.ToString() 
+ " 无效,请重新输入!");//其中e.UserState是SexValidationAsync方法中的第二个传参
            }

        }


        
#endregion


    }

}

上面,我们完成了如何利用WCF在服务器端进行数据校验,但这还不够,因为我们在后台进行数据校验时可能会处理一段时间,而如果等待时间过长,用户会认为程序卡住了,所以,我们需要给用户一个异步处理的提示信息,好让用户知道当前正在做什么,所以,下面我们来进一步完善异步校验工作,我们需要做一个提示界面。

二、如何制作一个异步等待数据校验的等待提示界面。
1、创建提示界面
在项目SLApplicationDataTest上添加一个新的Silverlight用户控件,如下图:

                        

定义等待提示界面,PleaseWaitValidate.xaml如下:

< UserControl x:Class = " SLApplicationDataTest.PleaseWaitValidate "
    xmlns
= " http://schemas.microsoft.com/winfx/2006/xaml/presentation "  
    xmlns:x
= " http://schemas.microsoft.com/winfx/2006/xaml "  
    Width
= " 300 "  Height = " 150 " >
        
< Grid x:Name = " LayoutRoot "   >
            
< Rectangle HorizontalAlignment = " Stretch "  VerticalAlignment = " Stretch "  Opacity = " 0.75 "  Fill = " WhiteSmoke "   />
            
< Border CornerRadius = " 30 "  Background = " CornflowerBlue "  Width = " 300 "  Height = " 150 " >
                
< TextBlock Text = " {Binding} "  Padding = " 60 "  Foreground = " Green "  FontSize = " 18 "   TextWrapping = " Wrap " />
            
</ Border >
        
</ Grid >
</ UserControl >

对此界面我们在后台编写两段代码(打开或关闭显示代码),PleaseWaitValidate.xaml.cs代码如下:

using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Net;
using  System.Windows;
using  System.Windows.Controls;
using  System.Windows.Documents;
using  System.Windows.Input;
using  System.Windows.Media;
using  System.Windows.Media.Animation;
using  System.Windows.Shapes;

namespace  SLApplicationDataTest
ExpandedBlockStart.gifContractedBlock.gif
{
    
public partial class PleaseWaitValidate : UserControl
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
public PleaseWaitValidate()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            InitializeComponent();
        }


ContractedSubBlock.gifExpandedSubBlockStart.gif        
打开显示#region 打开显示
        
public void StartWait()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
this.Visibility = Visibility.Visible;
        }

        
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif        
关闭显示#region 关闭显示
        
public void StopWait()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
this.Visibility = Visibility.Collapsed;
        }

        
#endregion

    }

}

 

2、引入提示界面。

在定义好提示等待界面后,我们需要要Silverlight主界面中引入和应用它。
引入方法如下,打开Page.xmal文件,加入下面代码:

 

 xmlns:myscreen = " clr-namespace:SLApplicationDataTest "

引入SLApplicationDataTest程序集,因为在此程序集中有我们定义的提示等待界面。
然后,在Page.xaml界面的DataGrid界面定义代码下加入:

   < myscreen:PleaseWaitValidate x:Name = " myWaitingSexValidateScreen "  Visibility = " Collapsed "  Margin = " 8,2,2,2 "  Width = " 300 "  Height = " 150 " >
        
</ myscreen:PleaseWaitValidate >

从而引入我们定义的等待提示界面控件。
至此Page.xaml全部代码如下:

ContractedBlock.gif ExpandedBlockStart.gif Code
<UserControl xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"  x:Class="SLApplicationDataTest.Page"
    xmlns
="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:myscreen
="clr-namespace:SLApplicationDataTest"
    Width
="600" Height="300">
  
<Canvas Width="600" Height="300" Background="Wheat">
        
<StackPanel Height="300"  Width="600" Background="White">
        
<StackPanel Orientation="Horizontal">
            
<Button x:Name="addButton" Content="Add" Margin="10"/>
            
<Button x:Name="deleteButton" Content="Delete" Margin="10"/>
        
</StackPanel>
        
<data:DataGrid x:Name="dgPeople" AutoGenerateColumns="False" >
            
<data:DataGrid.Columns>
                
<data:DataGridTextColumn     Header="Name"  Binding="{Binding Name}"  />
                
<data:DataGridTextColumn     Header="Sex"  Binding="{Binding Sex}"  />
                
<data:DataGridTemplateColumn Header="Age">
                    
<data:DataGridTemplateColumn.CellTemplate >
                        
<DataTemplate>
                            
<TextBlock  Text="{Binding Age}"  ToolTipService.ToolTip="请输入0至200之间的整数!"></TextBlock>
                        
</DataTemplate>
                    
</data:DataGridTemplateColumn.CellTemplate>
                    
<data:DataGridTemplateColumn.CellEditingTemplate>
                        
<DataTemplate>
                            
<TextBox Text="{Binding Age , Mode=TwoWay, NotifyOnValidationError=True,  ValidatesOnExceptions=True}" BindingValidationError="TextBox_BindingValidationError" 
                                     ToolTipService.ToolTip
="请输入0至200之间的整数!"></TextBox>
                        
</DataTemplate>
                    
</data:DataGridTemplateColumn.CellEditingTemplate>
                
</data:DataGridTemplateColumn>
                
<data:DataGridTextColumn     Header="Address"  Binding="{Binding Address}"  />
            
</data:DataGrid.Columns>
        
</data:DataGrid>
    
</StackPanel>
        
<myscreen:PleaseWaitValidate x:Name="myWaitingSexValidateScreen" Visibility="Collapsed" Margin="8,2,2,2" Width="300" Height="150">
        
</myscreen:PleaseWaitValidate>
   
</Canvas>
</UserControl>

3、应用提示界面
编辑Page.xaml.cs代码,加入下面程序段:

         #region   打开与关闭“等待校验窗口”
        
public   void  StartWait( string  message)
        {
            
this .myWaitingSexValidateScreen.DataContext  =  message;
            
this .myWaitingSexValidateScreen.StartWait();
        }

        
public   void  EndWait( string  message)
        {
            
this .myWaitingSexValidateScreen.DataContext  =  message;
            
this .myWaitingSexValidateScreen.StopWait();
        }
        
#endregion

编辑Person类定义代码,在数据校验代码段中加入下面代码:

 ((Page)Application.Current.RootVisual).StartWait( " 请稍候,正在校验性别输入! " );   // 打开等待提示界面,提示用户指定的提示信息

 ((Page)Application.Current.RootVisual).EndWait(
null );  // 关闭等待提示界面 


代码段如下:

   #region   性别输入校验程序:通过调用WCF服务来完成校验工作
        
private   void  ValidateSex( string  SexStr)
        {
            SexWCFClient sexCs 
=   new  SexWCFClient();
            sexCs.SexValidationCompleted 
+=   new  EventHandler < SexValidationCompletedEventArgs > (sexCs_SexValidationCompleted);
            ((Page)Application.Current.RootVisual).StartWait(
" 请稍候,正在校验性别输入! " );   // 打开等待提示界面,提示用户指定的提示信息
            sexCs.SexValidationAsync(SexStr, SexStr);   // 其中第二个SexStr为传入的UserState参数,将在sexCs_SexValidationCompleted中使用
        }

        
public   void  sexCs_SexValidationCompleted( object  sender, SexValidationCompletedEventArgs e)
        {
            ((Page)Application.Current.RootVisual).EndWait(
null );  // 关闭等待提示界面 
             if  ( ! e.Result)
            {
                HtmlPage.Window.Alert(e.UserState.ToString() 
+   "  无效,请重新输入! " ); // 其中e.UserState是SexValidationAsync方法中的第二个传参
            }
        }

        
#endregion

Person.cs全部代码如下:

using  System;
using  System.Net;
using  System.Windows;
using  System.Windows.Controls;
using  System.Windows.Documents;
using  System.Windows.Ink;
using  System.Windows.Input;
using  System.Windows.Media;
using  System.Windows.Media.Animation;
using  System.Windows.Shapes;
using  System.ComponentModel;  // 因为要用到INotifyPropertyChanged接口
using  SLApplicationDataTest.SexServiceReference;  // 因为要使用WCF服务
using  System.Windows.Browser;  // 因为要使用HtmlPage.Window.Alert


namespace  SLApplicationDataTest
ExpandedBlockStart.gifContractedBlock.gif
{
    
public class Person : INotifyPropertyChanged
ExpandedSubBlockStart.gifContractedSubBlock.gif    
{
        
private string _name;
        
private string _sex;
        
private int _age;
        
private string _address;

ContractedSubBlock.gifExpandedSubBlockStart.gif        
Constructors#region Constructors
ExpandedSubBlockStart.gifContractedSubBlock.gif        
public Person() { }

        
public Person(string NameStr, string SexStr, int AgeInt, string AddressStr)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
this._name = NameStr;
            
this._sex = SexStr;
            
this._age = AgeInt;
            
this._address = AddressStr;
        }

        
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif        
Properties#region Properties

        
public string Name
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return _name; }
            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (value == _name) return;
                _name 
= value;
                OnPropertyChanged(
"Name");
            }

        }


        
public string Sex
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return _sex; }
            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (value == _sex) return;
                _sex 
= value;
                OnPropertyChanged(
"Sex");
                ValidateSex(_sex); 
//调用WCF服务来进行数据校验
            }
        }


        
public int Age
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return _age; }
            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (value == _age) return;

                 
//如果输入的不是整数,则抛出异常
                try
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    Convert.ToInt32(value);
                }

                
catch(Exception ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
throw new Exception(ex.ToString());
                }

                 
                
//如果输入的整数不在合理范围同,则也抛出异常

                
if (value < 0 || value > 200)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
{
                    
throw new Exception("Age must be between 0 and 200");
                }



                _age 
= value;
                OnPropertyChanged(
"Age");
            }

        }


        
public string Address
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
get return _address; }
            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                
if (value == _address) return;
                _address 
= value;
                OnPropertyChanged(
"Address");
            }

        }

        
#endregion

ContractedSubBlock.gifExpandedSubBlockStart.gif        
INotifyPropertyChanged 接口实现#region INotifyPropertyChanged 接口实现
        
public event PropertyChangedEventHandler PropertyChanged;

        
protected void OnPropertyChanged(string name)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            
if (PropertyChanged != null)
                PropertyChanged(
thisnew PropertyChangedEventArgs(name));
        }

        
#endregion


ContractedSubBlock.gifExpandedSubBlockStart.gif        
性别输入校验程序:通过调用WCF服务来完成校验工作#region  性别输入校验程序:通过调用WCF服务来完成校验工作
        
private void ValidateSex(string SexStr)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
            SexWCFClient sexCs 
= new SexWCFClient();
            sexCs.SexValidationCompleted 
+= new EventHandler<SexValidationCompletedEventArgs>(sexCs_SexValidationCompleted);
           ((Page)Application.Current.RootVisual).StartWait(
"请稍候,正在校验性别输入!");  //打开等待提示界面,提示用户指定的提示信息
            sexCs.SexValidationAsync(SexStr, SexStr);  //其中第二个SexStr为传入的UserState参数,将在sexCs_SexValidationCompleted中使用
        }


        
public void sexCs_SexValidationCompleted(object sender, SexValidationCompletedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
{
             ((Page)Application.Current.RootVisual).EndWait(
null); //关闭等待提示界面 

            
if (!e.Result)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
{
                HtmlPage.Window.Alert(e.UserState.ToString() 
+ " 无效,请重新输入!");//其中e.UserState是SexValidationAsync方法中的第二个传参
            }

        }


        
#endregion


    }

}


至此,我们完成了对等待提示界面的定义,引用和应用。运行程序效果如下:
异步校验时的等待提示界面如下图:
                        
 异步校验未通过时的提示信息

                        



前往:Silverlight学习笔记清单
本文程序在Silverlight2.0和VS2008环境中调试通过。本文参照了部分网络资料,希望能够抛砖引玉,大家共同学习。
(转载本文请注明出处)

转载于:https://www.cnblogs.com/wsdj-ITtech/archive/2009/09/11/1564489.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值