silverlight与javascript交互操作

在silverlight开发中,我们可以使用js来调用silverlight中的方法(当然方法上要捆绑相应属性),也可以将指定
的js方法绑定到silverlight应用中的事件上.本DEMO演示了通过js调用完成silverlight数据列表控件(DataGrid)的数
据绑定操作,并通过DataGrid的EmployeeList_BeginningCellEdit事件将当前选取的数据行信息返回到js所绑定的
事件参数上,并调用该js方法显示选中数据行信息,如下图所示:

           
  
     下面介绍一下主要的开发过程:)
  
     首先,我们需要建立一个Silverlight Application ,名称为:Silverlight_JS_call.
  
     然后我们要在当前的项目中加入一个类文件,名称为:EmployeeInfo.cs.
  
     下面是相应的代码,相关内容见注释:  

[ScriptableType]
public class EmployeeInfo
{
    
/// <summary>
    
/// 雇员编号
    
/// </summary>
     [ScriptableMember]
    
public int EmployeeNo { get ; set ; }
    
/// <summary>
    
/// 雇员名称
    
/// </summary>
     [ScriptableMember]
    
public string EmployeeName { get ; set ; }
    
/// <summary>
    
/// 地址
    
/// </summary>
     [ScriptableMember]
    
public string Address { get ; set ; }
}
/// <summary>
/// 雇员事件参数(用于完成与js绑定事件参数)
/// </summary>
[ScriptableType]
public class EmployeeInfoEventArgs : EventArgs
{
     [ScriptableMember]
    
public EmployeeInfo employeeInfo{ get ; set ; }
}

/// <summary>
/// 要注册并在页面中使用的js调用脚本对象
/// </summary>
[ScriptableType]
public class JavaScriptableObject
{
    
/// <summary>
    
/// js捆绑的事件handler
    
/// </summary>
     [ScriptableMember]
    
public event EventHandler < EmployeeInfoEventArgs > SelectEmployeeInfo;

    
public void OnSelectEmployeeInfo(EmployeeInfo employeeinfo)
     {
        
if (SelectEmployeeInfo != null )
         {
             SelectEmployeeInfo(
this , new EmployeeInfoEventArgs()
             {
                 employeeInfo
= employeeinfo
             });
         }
     }
}

/// <summary>
/// 雇员信息管理类
/// </summary>
public class EmployeeManager
{
    
public IEnumerable < EmployeeInfo > employeeList;
    
/// <summary>
    
/// 初始化会员数据
    
/// </summary>
     public EmployeeManager()
     {
        
// 初始化雇员数据
         employeeList = new List < EmployeeInfo > ()
         {
            
new EmployeeInfo(){EmployeeNo = 10001 , EmployeeName = " 张三 " , Address = " 北京 " },
            
new EmployeeInfo(){EmployeeNo = 10002 , EmployeeName = " 李四 " , Address = " 北京 " },
            
new EmployeeInfo(){EmployeeNo = 10003 , EmployeeName = " 王五 " , Address = " 北京 " },
            
new EmployeeInfo(){EmployeeNo = 10004 , EmployeeName = " 马六 " , Address = " 北京 " },
            
new EmployeeInfo(){EmployeeNo = 10005 , EmployeeName = " 王大麻子 " , Address = " 北京 " },
            
new EmployeeInfo(){EmployeeNo = 10006 , EmployeeName = " 王宝强 " , Address = " 北京 " },
            
new EmployeeInfo(){EmployeeNo = 10007 , EmployeeName = " 王蛋蛋 " , Address = " 北京 " },
            
new EmployeeInfo(){EmployeeNo = 10008 , EmployeeName = " 王五强 " , Address = " 北京 " }
         };
     }

    
/// <summary>
    
/// 获取指定数量的雇员数据
    
/// </summary>
    
/// <param name="count"> 要获取的雇员信息数 </param>
    
/// <returns></returns>     
     public IEnumerable < EmployeeInfo > GetEmployeeList( int count)
     {
        
return (from e in employeeList
                     select
new EmployeeInfo
                     {
                         EmployeeNo
= e.EmployeeNo,
                         EmployeeName
= e.EmployeeName,
                         Address
= e.Address

                     }).Take(count);
     }
}

    上面代码中要注意的是[ScriptableType]和[ScriptableMember],前者允许Silverlight把类型暴露给脚本,后者
则会把成员方法或属性暴露给脚本.

  而下面的代码就是page.xaml中的内容:  

< UserControl xmlns:my ="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data"    x:Class ="Silverlight_JS_call.Page"
     xmlns
="http://schemas.microsoft.com/client/2007"
     xmlns:x
="http://schemas.microsoft.com/winfx/2006/xaml"
     Width
="400" Height ="300" >
    
< Grid x:Name ="LayoutRoot" Background ="White" >
        
< Grid.RowDefinitions >
            
< RowDefinition Height ="300" />
        
</ Grid.RowDefinitions >
        
< my:DataGrid   x:Name ="EmployeeList"    Grid.Row ="1"    AutoGenerateColumns ="True" Height ="280" Margin ="5,5,5,5" AlternatingRowBackground ="AliceBlue" RowBackground ="BlanchedAlmond" >
        
</ my:DataGrid >
   
</ Grid >
</ UserControl >

  下面则是相应的page.xaml.cs文件的内容(相关内容见注释):  

[ScriptableType]
public partial class Page : UserControl
{
    
public Page()
     {
         InitializeComponent();
        
this .Loaded += Page_Loaded;
        
this .EmployeeList.BeginningCellEdit += new EventHandler < DataGridCellEditingCancelEventArgs > (EmployeeList_BeginningCellEdit);
     }
    
     
    
void Page_Loaded( object sender, RoutedEventArgs e)
     {
         javaScriptableObject
= new JavaScriptableObject();
        
// 注册js可用的类型(详情见Silverlight_JS_callTestPage.aspx中的js代码)
         HtmlPage.RegisterScriptableObject( " EmployeeObject " , javaScriptableObject);
         HtmlPage.RegisterScriptableObject(
" Page " , this );
     }
    
    
/// <summary>
    
/// 击编辑雇员列表信息事件
    
/// </summary>
    
/// <param name="sender"></param>
    
/// <param name="e"></param>
     void EmployeeList_BeginningCellEdit( object sender, DataGridCellEditingCancelEventArgs e)
     {
        
// 当有要编辑的信息时
         if (EmployeeList.SelectedItem != null )
         {
             EmployeeInfo employeeInfo
= EmployeeList.SelectedItem as EmployeeInfo;
            
// 执行选中信息事件操作(最终会执行js所绑定的function代码)
             javaScriptableObject.OnSelectEmployeeInfo(employeeInfo);
         }
     }     

  
// 这里必须声明是public,否则js调用该方法时会报错
     [ScriptableMember]
    
public void LoadData( int count)
     {
        
// 加载指定数据的雇员信息
         EmployeeList.ItemsSource = new EmployeeManager().GetEmployeeList(count);
     }

     JavaScriptableObject javaScriptableObject;       
}


    上面代码要注意的是RegisterScriptableObject方法的调用,它用来注册可被脚本使用的对象实例,
与它相对应的还有一个方法RegisterCreateableType,它用于注册可被脚本使用的类型.

  到这里,基本上完成的cs代码的开发工作.下面则是相应的js调用以及事件绑定代码了,请看:

< script type = " text/javascript " >
   
// 显示选取的雇员信息
    // 注:args为cs中的EmployeeInfoEventArgs类型实例
    function ShowSelectEmployeeInfo(sender, args)
    {  
       $get(
" employeeNo " ).value = args.employeeInfo.EmployeeNo;
       $get(
" employeeName " ).value = args.employeeInfo.EmployeeName;
       $get(
" employeeAddress " ).value = args.employeeInfo.Address;
       $get(
" results " ).style.display = ' block ' ;
    }
   
   
// 初始化操作,绑定到input元素("加载数据")的click事件上,详情参见aspx文件
    function Init(obj)
    {
       
// 绑定上面的js函数到silverlight的事件handler
        $get( " Xaml1 " ).content.EmployeeObject.SelectEmployeeInfo = ShowSelectEmployeeInfo;
       
       
// 加载雇员信息     
        $get( " Xaml1 " ).content.Page.LoadData(parseInt(obj.title));              
    }
< / script>

           
    另外在进行初始化操作,这里使用了onclick方法来执行操作,而不是直接运行相应代码.原因是
silverlight对象加载是使用了异步方式,这样会造成对象实例化完成时间迟于页面JS脚本的运行时间.
这样设计的原因,我个人认为主要是UE方面的考虑.而这时如果脚本中直接调用对象实例化的属性或
方法时,会出现对象未知的情况.

猜你喜欢

转载自blog.csdn.net/luochengbang/article/details/5561791