• Silverlight 的 Data Bindings:Silverlight 與 ASP.NET Ajax


    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" T
    t
    ="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

  • 相关阅读:
    ZQUOJ 1964 Hamilton回路(状压dp)
    ZQUOJ 1398 Hamilton路径(DFS,稀疏图,n≤40)
    2019 CCPC
    百度之星初赛第三场 1002 最短路2 (Floyd算法优化)
    2019牛客暑期多校训练营(第四场)J free(分层图最短路/模板题)
    2019牛客暑期多校训练营(第一场)I Points Division(DP+线段树)
    2019牛客暑期多校训练营(第七场)A String(枚举)
    2019牛客暑期多校训练营(第九场)B Quadratic equation(欧拉准则+解二次剩余)
    二次剩余系解法
    二次剩余的判断(欧拉准则)
  • 原文地址:https://www.cnblogs.com/mz121star/p/867319.html
Copyright © 2020-2023  润新知