zoukankan      html  css  js  c++  java
  • 在两个Silverlight应用间数据通信(包括与Flash通信)

         因为Silverlight可以访问HTML中的DOM元素以及调用HTML页面中的JS方法,并且可以将自身的方法“暴露”
    给HTML页面中的JS方法(通过[ScriptableMember]),所以我们可以利用这一特点来实现两个Silverlight应用
    程序之间的数据通信。为了直观起见,本人做了这个DEMO,希望能够对大家在理解上有所帮助。

         本DEMO的工作流程如下:    
        
         Silverlight 1 调用HTML中的JS方法,而该方法会去调用Silverlight 2中“暴露”的方法来显示选中的数
    据。  

         请大家先看一下这个DEMO的运行效果,如下图所示:
         
         
      
         在上图中分别有两个Silverlight应用,一个是雇员列表,一个是详细信息。其中的雇员列表是我以前在园
    子里发表过的一遍文章中提到的DEMO,这里只是为了便于演示而简单的加以改造,其雇员类信息如下:

     

    [ScriptableType]
    public class EmployeeInfo
    {
        
    /// <summary>
        
    /// 雇员编号
        
    /// </summary>
        [ScriptableMember]
        
    public int EmployeeNo { getset; }
        
    /// <summary>
        
    /// 雇员名称
        
    /// </summary>
        [ScriptableMember]
        
    public string EmployeeName { getset; }
        
    /// <summary>
        
    /// 地址
        
    /// </summary>
        [ScriptableMember]
        
    public string Address { getset; }
    }

        
        上面的ScriptableType,ScriptableMember属性绑写是为了让html中的脚本代码可以访问(即可见)。
       
        而下面的代码则是为了定义一个“脚本对象类”及其事件处理(包括参数)。    

    /// <summary>
    /// 雇员事件参数(用于完成与js绑定事件参数)
    /// </summary>
    [ScriptableType]
    public class EmployeeInfoEventArgs : EventArgs
    {
        [ScriptableMember]
        
    public EmployeeInfo employeeInfo { getset; }
    }

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

        
    public void OnSelectEmployeeInfo(EmployeeInfo employeeinfo)
        {
            
    if (SelectEmployeeInfo != null)
            {
                SelectEmployeeInfo(
    thisnew 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);
        }

    }


        有了数据和数据结构,我们可以在应用程序中给列表控件绑定数据源了,如下:
        

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


        
        当然DEMO中所提供的功能里有“选取某一行雇员信息”的操作,其实现方法如下:

     

    /// <summary>
    /// 单击编辑雇员列表信息事件
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void EmployeeList_BeginningEdit(object sender, DataGridBeginningEditEventArgs e)
    {
        
    //当有要编辑的信息时
        if (EmployeeList.SelectedItem != null)
        {
            EmployeeInfo employeeInfo 
    = EmployeeList.SelectedItem as EmployeeInfo;
            
    //执行选中信息事件操作(最终会执行js所绑定的function代码)
            javaScriptableObject.OnSelectEmployeeInfo(employeeInfo);
        }
    }

         大家请注意上面的这一行代码:     

    javaScriptableObject.OnSelectEmployeeInfo(employeeInfo);

         
         其完成的就是对HTML页面上JS绑定事件的调用,其JS绑写事件代码如下:
         

    //初始化操作
    function Init(obj) {
        
    //绑定js函数到silverlight的事件处理器
        $get("Xaml1").content.EmployeeObject.SelectEmployeeInfo = ShowSelectEmployeeInfo;
        
    }

            
         当然,上面还有一个内容没有说明,即EmployeeObject对象是从哪来的,其实它就是我们公布到HTML中让
     JS可以访问的对象JavaScriptableObject的实例,如下:      

    JavaScriptableObject javaScriptableObject;
    void Page_Loaded(object sender, RoutedEventArgs e)
    {
        javaScriptableObject 
    = new JavaScriptableObject();
        
    //注册js可用的类型(详情见Silverlight_JS_callTestPage.aspx中的js代码)
        HtmlPage.RegisterScriptableObject("EmployeeObject", javaScriptableObject);
        ..
    }


                    
         而JS方法"ShowSelectEmployeeInfo"即是实现对Silverlight 2应用中“暴露”方法的调用。其内容如下:    

    //显示选取的雇员信息
    function ShowSelectEmployeeInfo(sender, args) {
        $get(
    "Xaml2").content.Page.LoadDetailData(parseInt(args.employeeInfo.EmployeeNo),
                                                  args.employeeInfo.EmployeeName,
                                                  args.employeeInfo.Address);
    }


        而Silverlight 2应用中的LoadDetailData方法所实现的就是将选中的单个雇员信息进行显示,如下:     

    //这里必须声明是public,否则js调用该方法时会报错
    [ScriptableMember]
    public void LoadDetailData(int employeeNo, string employeeName, string address)
    {
        
    //加载指定数据的雇员信息
        EmployeeNo.Text = employeeNo.ToString();
        EmployeeName.Text 
    = employeeName;
        Address.Text 
    = address;
    }

        
        到这里,基本上DEMO中的主要内容就介绍完了。
       
        下面再给大家演示一个Silverlight与FLASH进行数据通信 的例子,其实现的功能如下:   
     
        在Silverlight应用中拖动一张图片,在右侧的FLASH区域中相应的FLASH对象跟着被“移动”,其效果如下
    图所示:
     
     
     
       

         其实这个DEMO最初的原型出自微软件的黄继佳,我是在一次SILVERLIGHT培训中看到他这个演示,当时
    我想实现原理应该与本文所提到的大同小异,后来被证实现确实如此。当然他的演示中实现的JS代码很简单,
    完全就是用纯JS来实现即可。我这里并未完全使用了他的模型代码。因为上面所说的是在CS代码中进行事件的
    绑定及其相关操作,所以我还是照上面所提供的思路重新写了这个DEMO,实现的效果与黄纪佳的原型基本相似。
    因为篇幅起见,这里就不多做赘述了,大家下载代码后一看便知(SLImage.xaml.cs和SLtoFlash.htm文件)。
     
        好的,今天的内容就先到这里了。
       
        感兴趣的朋友可以在回复中进行讨论。

        作者:代震军,daizhj
       
        tags:silverlight, flash ,通信,数据传输
       
        源码下载,请点击这里
     
       
           
         

  • 相关阅读:
    灰姑娘的水晶鞋(NOIP模拟赛Round 7)
    小红帽的画笔(NOIP模拟赛Round 7)
    YYH的球盒游戏(NOIP模拟赛Round 6)
    YYH的营救计划(NOIP模拟赛Round 6)
    imrersize函数
    数字图像基础知识之灰度图像,彩色图像和矩阵
    灰度变换之彩色变灰色
    数字图像基础知识
    灰度变换之灰度线性拉伸(算法1)
    C结构体变量2种运算(比如链表的结点)(区别与java)
  • 原文地址:https://www.cnblogs.com/daizhj/p/1314796.html
Copyright © 2011-2022 走看看