加入收藏 | 网站地图 | | RSS | WAP
你好,游客 登录 注册 搜索

Silverlight 的 Data Bindings:Silverlight 与 ASP.

[日期:2007-11-27] 作者: 来源: [字体: ]
     不可否认,对于网页美工人员或是动画设计师而言,Silverlight 提供了 Flash 以外的一个画布,令她们可尽情挥洒创意!但对于设计师而言,Silverlight 如何结合资料库来呈现资料则是更具吸引力的课题,很明显的!Silverlight 1.0 RC 与 Silverlight 1.1 并不支援 Data Binding 机制,而且目前对于中文显示仍存在着问题(下载字型不算是个解法,因为有法律问题),不过如果这个问题获得解决,Silverlight 结合资料库后所呈现的效果,相信会给客户完全不同的网页操作感受,当然!前提得要 Silverlight 支援 Data Bindings,否则一切都是纸上谈兵罢了。要令 Silverlight 支援 Data Bindings 说来也不难,只要处理几个关键问题即可。一、资料提供者为何?ASP.NET Ajax 的 PageMethods/Web Service 可以胜任此工作,如下列程式片段所示。
  
  private static DataTable BuildDataCache()
   {
   if (HttpRuntime.Cache["DataCache_Employees"] != null)
   return HttpRuntime.Cache["DataCache_Employees"] as DataTable;
   else
   {
   using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings[
  "NorthwindConnectionString"].ConnectionString))
   {
   SqlDataAdapter adapter = new SqlDataAdapter(
  "SELECT * FROM Employees ORDER BY EmployeeID", conn);
   DataTable table = new DataTable("Employees");
   adapter.Fill(table);
   HttpRuntime.Cache["DataCache_Employees"] = table;
   return table;
   }
   }
   }
  
   [WebMethod]
   public static Employee GetData(int index)
   {
   DataTable table = BuildDataCache();
   return new Employee(table.DefaultView[index]);
   }
  
   [WebMethod]
   public static int GetCount()
   {
   DataTable table = BuildDataCache();
   return table.DefaultView.Count;
   }
  
   protected void Button1_Click(object sender, EventArgs e)
   {
   }
  }
  
  [Serializable]
  public class Employee
  {
   [NonSerialized]
   private DataRowView _rv = null;
  
   public string EmployeeID
   {
   get
   {
   return (_rv.Row.IsNull("EmployeeID") ? string.Empty : _rv["EmployeeID"].ToString());
   }
   }
  
   public string LastName
   {
   get
   {
   return (_rv.Row.IsNull("LastName") ? string.Empty : (string)_rv["LastName"]);
   }
   }
  
   public string FirstName
   {
   get
   {
   return (_rv.Row.IsNull("FirstName") ? string.Empty : (string)_rv["FirstName"]);
   }
   }
  
   public string Title
   {
   get
   {
   return (_rv.Row.IsNull("Title") ? string.Empty : (string)_rv["Title"]);
   }
   }
  
   public string HireDate
   {
   get
   {
   return (_rv.Row.IsNull("HireDate") ?
  string.Empty : ((DateTime)_rv["HireDate"]).ToShortDateString());
   }
   }
  
   public Employee(DataRowView rv)
   {
   _rv = rv;
   }
  }
  
  
  
  运用 ASP.NET Ajax 及 JSON,我们可以轻易的用 JavaScript 来取得资料库的资料,接着只要将资料设定给指定 Silverlight 控制项即可,这个工作可以简单化也可以复杂化,简单的作法是直接在 JavaScript 以 findName 来取得控制项,然后一一设定其属性值。
  
  handleLoad: function(plugIn, userContext, rootElement)
  {
   this.plugIn = plugIn;
   this.dataContext = rootElement.children.getItem(0);
   PageMethods.GetCount(this.OnSucceeded,this.OnFailed,this);
   this.receiveData(this.currentDataIndex);
  },
  OnSucceeded: function(result, userContext, methodName)
  {
   if (methodName == "GetData")
   {
   userContext.displayData(result);
   }
   else if(methodName == "GetCount")
   userContext.recordCount = result;
  },
  OnFailed:function(error, userContext, methodName)
  {
   if(error !== null)
   {
   alert(error.get_message());
   }
  },
  displayData: function(data)
  {
   var idCtrl = this.dataContext.findName('txtEmployeeID');
   var firstNameCtrl = this.dataContext.findName('txtLastName');
   var lastNameCtrl = this.dataContext.findName('txtFirstName');
   var titleCtrl = this.dataContext.findName('txtTitle');
   var hireDateCtrl = this.dataContext.findName('txtHireDate');
   var imgCtrl = this.dataContext.findName("imgPhoto");
   idCtrl.text = data.EmployeeID;
   firstNameCtrl.text = data.FirstName;
   lastNameCtrl.text = data.LastName;
   titleCtrl.text = data.Title;
   hireDateCtrl.text = data.HireDate;
   imgCtrl.source = "Default.aspx?ID="+idCtrl.text;
   this.dataContext.findName("imgAnimation").begin();
  }
  
  
  这种做法的缺点是设计师得用 JavaScript 写下许多程式码。另一种做法是利用 Silverlight 控制项的 Tag 属性,指定 Binding Expression,然后于 JavaScript 中巡览她们来一一指定值,如下列片段所示。
  
  <Canvas XMLns="http://schemas.microsoft.com/client/2007"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
   <Canvas Name="DataDemo" Height="600" Width="800" Tag="BindingContext:GetData,GetCount">
   <Canvas.Background>
   <LinearGradientBrush>
   <GradientStop Color="Yellow" Offset="0.0" />
   <GradientStop Color="Orange" Offset="0.5" />
   <GradientStop Color="Red" Offset="1.0" />
   </LinearGradientBrush>
   </Canvas.Background>
   <TextBlock Tag="BindingField:EmployeeID;BindingProperty:Text" Name="txtEmployeeID" Width="144" Height="24" Canvas.Left="166" Canvas.Top="23" Tt="A00001" TextWrapping="Wrap"/>
   <TextBlock Tag="BindingField:LastName;BindingProperty:Text" Name="txtLastName" Width="320" Height="24" Canvas.Left="500" Canvas.Top="23" Text="Alean Company" TextWrapping="Wrap"/>
   <TextBlock Tag="BindingField:FirstName;BindingProperty:Text" Name="txtFirstName" Width="320" Height="24" Canvas.Left="166" Canvas.Top="72" Text="Jeffray" TextWrapping="Wrap"/>
   <TextBlock Tag="BindingField:Title;BindingProperty:Text" Name="txtTitle" Width="576" Height="24" Canvas.Left="166" Canvas.Top="122" Text="Taipen 101" TextWrapping="Wrap"/>
   <TextBlock Tag="BindingField:HireDate;BindingProperty:Text" Name="txtHireDate" Width="576" Height="24" Canvas.Left="166" Canvas.Top="171" Text="2005/3/4" TextWrapping="Wrap"/>
   <Image Name="imgPhoto" Tag="BindingField:EmployeeID;BindingProperty:Source;Format:Default.aspx?ID={0}" Width="357" Height="206" Canvas.Left="400" Canvas.Top="301">
   <Image.Triggers>
   <EventTrigger RoutedEvent="Image.Loaded">
   <BeginStoryboard>
   <Storyboard Name="imgAnimation">
   <DoubleAnimation
   Storyboard.TargetName="imgPhoto"
   Storyboard.TargetProperty="Opacity"
   From="0.0" To="1.0" Duration="0:0:6"/>
   </Storyboard>
   </BeginStoryboard>
   </EventTrigger>
   </Image.Triggers>
   </Image>
   <TextBlock Name="txtLabel1" Width="114" Height="24" Canvas.Left="18" Canvas.Top="23" Text="Employee ID:" TextWrapping="Wrap"/>
   <TextBlock Name="txtLabel1_Copy" Width="120" Height="24" Canvas.Left="349" Canvas.Top="23" Text="Last Name:" TextWrapping="Wrap"/>
   <TextBlock Name="txtLabel1_Copy1" Width="130" Height="24" Canvas.Left="18" Canvas.Top="72" Text="First Name:" TextWrapping="Wrap"/>
   <TextBlock Name="txtLabel1_Copy2" Width="104" Height="24" Canvas.Left="18" Canvas.Top="122" Text="Title :" TextWrapping="Wrap"/>
   <TextBlock Name="txtLabel1_Copy3" Width="93" Height="24" Canvas.Left="18" Canvas.Top="171" Text="Hire Date:" TextWrapping="Wrap"/>
   </Canvas>
  </Canvas>
  
  
  
  那如何解析 Tag 的 Binding Expression 并指定值呢?答案是利用 Silverlight 的 JavaScript 支援,一一巡览所有控制项,一一解析 Tag,然后再指定值。
  
  /////////////////////////////////////////////////////////////////////////
  // Silverlight Data Binding Helper 0.1
  /////////////////////////////////////////////////////////////////////////
  
  if (!window.SilverlightBinding)
   window.SilverlightBinding = {};
  
  SilverlightBinding.BindingData = function(ctrl,bindingExpression)
  {
   var bindings = bindingExpression.split(';');
   this.bindingComplete = false;
   this.ctrl = ctrl;
   for(var i = 0; i < bindings.length; i++)
   {
   var temp = bindings[i].split(':');
   if(temp.length != 2)
   {
   this.bindingComplete = false;
   return;
   }
   if(temp[0] == 'BindingField')
   this.bindingField = temp[1];
   else if(temp[0] == 'BindingProperty')
   this.bindingProperty = temp[1];
   else if(temp[0] == 'Format')
   this.format = temp[1];
   }
   this.bindingComplete = true;
  }
  
  SilverlightBinding.BindingData.prototype =
  {
   updateValue : function(dataItem)
   {
   if(this.bindingComplete)
   {
   if(this.format)
   eval('this.ctrl.'+this.bindingProperty+
  " = this.format.replace('{0}',dataItem."+this.bindingField+');');
   else
   eval('this.ctrl.'+this.bindingProperty+' = dataItem.'+this.bindingField+';');
   }
   }
  }
  
  SilverlightBinding.BindingContext = function(bindingContainer)
  {
   var parseBinding = bindingContainer.tag.split(':');
   this.bindingComplete = false;
   this.bindingContainer = bindingContainer;
   this.bindingControls = new Array();
   this.currentDataIndex = 0;
   this.recordCount = 0;
   if(parseBinding.length == 2 && parseBinding[0] == "BindingContext")
   {
   var bindingMethods = parseBinding[1].split(',');
   if(bindingMethods.length == 2)
   {
   this.bindingMethod = bindingMethods[0];
   this.bindingCountMethod = bindingMethods[1];
   this.bindingComplete = true;
   }
   }
   if(!this.bindingComplete) alert('ERROR,Binding Failed.');
  }
  
  SilverlightBinding.BindingContext.prototype =
  {
   _childWorker : function(parent,parseParent)
   {
   if(parent.tag && parent.tag != '')
   {
   if(parseParent)
   {
   var bindingData = new SilverlightBinding.BindingData(parent,parent.tag);
   if(bindingData.bindingComplete)
   {
   this.bindingControls.length++;
   this.bindingControls[this.bindingControls.length-1] = bindingData;
   }
   else
   delete bindingData;
   }
   try
   {
   var temp = parent.children;
   }
   catch(err)
   {
   return;
   }
   for(var i = 0; i < parent.children.count; i++)
   this._childWorker(parent.children.getItem(i),true);
   }
   },
   initialize:function()
   {
   this._childWorker(this.bindingContainer,false);
   this._receiveCount();
   this._receiveData(0);
   },
   OnSucceeded: function(result, userContext, methodName)
   {
   if (methodName == userContext.bindingMethod)
   {
   for(var i = 0; i < userContext.bindingControls.length; i++)
   userContext.bindingControls[i].updateValue(result);
   }
   else if(methodName == userContext.bindingCountMethod)
   userContext.recordCount = result;
   },
   OnFailed:function(error, userContext, methodName)
   {
   if(error !== null)
   {
   alert(error.get_message());
   }
   },
   _receiveData: function(index)
   {
   eval('PageMethods.'+this.bindingMethod+
  '(index,this.OnSucceeded,this.OnFailed,this);');
   },
   _receiveCount: function()
   {
   eval('PageMethods.'+this.bindingCountMethod+
  '(this.OnSucceeded,this.OnFailed,this);');
   },
   next:function()
   {
   if(this.currentDataIndex+1 >= this.recordCount)
   return;
   this._receiveData(++this.currentDataIndex);
   },
   prev:function()
   {
   if(this.currentDataIndex -1 < 0)
   return;
   this._receiveData(--this.currentDataIndex);
   }
  }
  
  
  使用此 JavaScript 物件的方法很简单,只要于 handleLoad 中建立此物件,然后将 Silverlight 的根控制项传入即可。
  
  handleLoad: function(plugIn, userContext, rootElement)
  {
   this.plugIn = plugIn;
   this.dataContext = rootElement.children.getItem(0);
   this.bindingContext =
   new SilverlightBinding.BindingContext(rootElement.children.getItem(0));
   this.bindingContext.initialize();
  }
  
  切换上下笔时也很简单。
  
  function Next()
  {
   window.Silverlight.current_DataContext.bindingContext.next();
   window.Silverlight.current_DataContext.dataContext.findName("imgAnimation").begin();
  }
  
  function Prev()
  {
   window.Silverlight.current_DataContext.bindingContext.prev();
   window.Silverlight.current_DataContext.dataContext.findName("imgAnimation").begin();
  }
  
  
  下图为执行画面。
  
  
  本例下载位址:
  http://www.dreams.idv.tw/~code6421/files/SLDataDemo1.zip
  
  原文:http://www.microsoft.com/taiwan/msdn/columns/huang_jhong_cheng/Silverlight_Data_Bindings.htm
  
  
  
    

关键词:

收藏 推荐 打印 | 录入:blue1000 | 阅读:
本文评论   查看全部评论 (2)
表情: 姓名: 字数
点评:
       
评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事/刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款
第 2 楼
* 匿名 发表于 2016/12/25 14:23:02
http://www.blue1000.com/bkhtml/c17/2013-04/71127.htm 出生证明范本 http://www.135995.com/show/5615.html 出生证明格式 http://www.135995.com/show/5613.html
第 1 楼
* 匿名 发表于 2016/12/24 14:14:10
http://www.blue1000.com/bkhtml/c17/2013-04/71127.htm 演讲稿 http://www.135995.com/m-yanjianggao/ “严以修身”专题学习研讨会发言稿 http://www.135995.com/show/19550.html