商务合作:179001057@qq.com

Silverlight 的 DataBindings

技术2022-05-11  0


某平台价值19860元的编程课程资料免费领取【点我领取】


Silverlight Data Bindings Silverlight ASP.NET Ajax     文/黃忠成  不可否認,對於網頁美工人員或是動畫設計師而言,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"Text="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  

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1720494


最新回复(0)