概述 Silverlight DataBindings for 1.1 (Managed code) 文 / 黃忠成 RC1方興未艾, RC2已在路上了,看來1.0 Release之日不遠了!前面一篇文章利用了PageMethods與JavaScript為Silverlight 1.0RC加上DataBindings的功能,此次舞台換到了Silverlight 1.1 Alpha
Silverlight DataBindings for 1.1 (Managed code) 文 / 黃忠成 RC1方興未艾,
RC2已在路上了,看來1.0 Release之日不遠了!前面一篇文章利用了PageMethods與JavaScript為Silverlight 1.0RC加上DataBindings的功能,此次舞台換到了Silverlight 1.1 Alpha Refresh及Visual Studio 2008 Beta 2上,與1.1時不同,這次已無法用單一的Web Site模式實作,基於ASP.NET AJAX與Silverlight所使用的CLR Runtime不同,我們必須將Silverlight與ASP.NET AJAX拆開,別誤會!這並非意味你無法將Silverlight與ASP.NET AJAX放在同一個虛擬目錄下,Silverlight 1.1使用的Binary目錄是ClIEntBin,ASP.NET是Bin,兩者並無衝突,限制只在於你必須將Silverlight與ASP.NET AJAX分成兩個Project來編譯,在Silverlight編譯完成後將.xaml、.Js複製到ASP.NET AJAX的專案目錄下,再將.dll複製到ASP.NET AJAX的ClIEntBin目錄下即可。回到主題,在Silverlight 1.1中,實現Data Bindings除了可以用前一篇文章的JavaScript技巧外,還多了一個選擇,那就是使用C#等Managed的語言,SLDH.Js的C#版本如下。 SLDH.cs
///////////////////////////////////////////////////////////////////////// // Silverlight Data Binding Helper 0.1 for Silverlight 1.1 Alpha Refresh ///////////////////////////////////////////////////////////////////////// using System; using System.Text; using System.IO; using System.Net; using System.Reflection; using System.linq; using System.Collections.Generic; using System.windows; using System.windows.Controls; using System.windows.documents; using System.windows.Ink; using System.windows.input; using System.windows.Media; using System.windows.Media.Animation; using System.windows.Shapes; using System.windows.browser.Net; using System.windows.browser.Serialization; namespace SilverlightDataHelper { public class JsONDaTarow { private List<object> _columns; private List<object> _values; public object this[int index] { get { return _values[index]; } } public object this[string name] { get { for (int i = 0; i < _columns.Count; i++) { if (((string)_columns[i]).Equals(name)) return _values[i]; } return null; } } internal JsONDaTarow(object[] columns,object[] values) { _columns = new List<object>(columns); _values = new List<object>(values); } } public class BindingData { private bool _bindingComplete = false; private string _bindingProperty = string.Empty; private string _bindingFIEld = string.Empty; private FrameworkElement _control; private string _format = string.Empty; private PropertyInfo _cachedProp = null; public bool BindingComplete { get { return this._bindingComplete; } } public string BindingProperty { get { return _bindingProperty; } } public string BindingFIEld { get { return _bindingFIEld; } } public FrameworkElement Control { get { return _control; } } public string Format { get { return _format; } set { _format = value; } } public voID UpdateValue(JsONDaTarow dataItem) { if (_bindingComplete) { if (_cachedProp == null) { _cachedProp = _control.GetType().GetProperty(_bindingProperty); if (_cachedProp == null) _bindingComplete = false; } if (_cachedProp != null && Format != string.Empty) { if (_cachedProp.PropertyType == typeof(Uri)) { Uri uri = new Uri(string.Format(Format, dataItem[BindingFIEld]),UriKind.relative); _cachedProp.SetValue(_control,uri,null); } else _cachedProp.SetValue(_control,string.Format(Format, dataItem[BindingFIEld]),null); } else if (_cachedProp != null) _cachedProp.SetValue(_control,dataItem[BindingFIEld],null); } } public BindingData(FrameworkElement ctrl,string bindingExpression) { string[] bindings = bindingExpression.Split(';'); _bindingComplete = false; _control = ctrl; for (int i = 0; i < bindings.Length; i++) { string[] temp = bindings[i].Split(':'); if (temp.Length != 2) { _bindingComplete = false; return; } if (temp[0].Tolower() == "bindingfIEld") _bindingFIEld = temp[1]; else if (temp[0].Tolower() == "bindingproperty") _bindingProperty = temp[1]; else if (temp[0].Tolower() == "format") _format = temp[1]; } if (_bindingFIEld != string.Empty && _bindingProperty != string.Empty) _bindingComplete = true; } } public class BindingContext { private Panel _container; private List<BindingData> _bindingControls = null; private bool _bindingComplete = false; private int _position = 0; private int _count = -1; private string _serviceUrl = string.Empty; private string _bindingMethod = string.Empty; private string _bindingCountMethod = string.Empty; private string _countMethod = string.Empty; public int position { get { return _position; } set { if (_position != value && value < Count && value >= 0) { _position = value; UpdateBinding(); } } } public int Count { get { return _count; } } public bool BindingComplete { get { return _bindingComplete; } } public List<BindingData> BindingControls { get { if (_bindingControls == null) _bindingControls = new List<BindingData>(); return _bindingControls; } } private voID ChilDWorker(FrameworkElement elem) { string expRSSsion = elem.Tag == null ? string.Empty : elem.Tag; BindingData data = new BindingData(elem,expRSSsion); if (data.BindingComplete) BindingControls.Add(data); if (elem is Panel) { Panel pnl = (Panel)elem; for (int i = 0; i < pnl.Children.Count; i++) { if (pnl.Children[i] is FrameworkElement) ChilDWorker((FrameworkElement)pnl.Children[i]); } } } private voID FetchCount() { browserhttpWebRequest request = new browserhttpWebRequest(new Uri(_serviceUrl + "/" + _bindingCountMethod,UriKind.relative)); request.ContentType = "application/Json; charset=utf-8"; request.Method = "POST"; request.ContentLength = 0; request.Referer = System.windows.browser.HTMLPage.documentUri.absolutePath; request.Accept = "/*/"; httpWebResponse response = request.GetResponse(); StreamReader sr = new StreamReader(response.GetResponseStream()); JavaScriptSerializer serializer = new JavaScriptSerializer(); string data = sr.ReadToEnd(); _count = serializer.Deserialize<int>(data); sr.Close(); response.Close(); request.Close(); } private JsONDaTarow FetchData(int index) { browserhttpWebRequest request = new browserhttpWebRequest(new Uri(_serviceUrl + "/" + _bindingMethod,UriKind.relative)); JavaScriptSerializer serializer = new JavaScriptSerializer(); request.ContentType = "application/Json; charset=utf-8"; request.Method = "POST"; request.Referer = System.windows.browser.HTMLPage.documentUri.absolutePath; request.Accept = "/*/"; Stream reqStream = request.GetRequestStream(); byte[] buff = EnCoding.UTF8.GetBytes("{index:" + index.ToString() + "}"); reqStream.Write(buff,buff.Length); request.ContentLength = buff.Length; httpWebResponse response = request.GetResponse(); StreamReader sr = new StreamReader(response.GetResponseStream()); string data = sr.ReadToEnd(); sr.Close(); response.Close(); request.Close(); object[] parsedData = serializer.Deserialize<object[]>(data); return new JsONDaTarow((object[])parsedData[0],(object[])parsedData[1]); } private voID UpdateBinding() { JsONDaTarow row = FetchData(position); foreach (BindingData item in BindingControls) item.UpdateValue(row); } public voID Initialize() { ChilDWorker(_container); FetchCount(); UpdateBinding(); } public BindingContext(Panel container) { _container = container; if (_container.Tag == null) { _bindingComplete = false; return; } string[] parseBinding = container.Tag.Split(':'); _bindingComplete = false; if (parseBinding.Length == 2 && parseBinding[0].Tolower() == "bindingcontext") { string[] bindingMethods = parseBinding[1].Split(','); if (bindingMethods.Length == 3) { _serviceUrl = bindingMethods[0]; _bindingMethod = bindingMethods[1]; _bindingCountMethod = bindingMethods[2]; _bindingComplete = true; } } if (_bindingComplete) ChilDWorker(container); } } } |
ㄟ...程式碼變長了哦~~~ >"<,在某些情況下,Managed Code不見得比JavaScript簡單吧!只是別忘了,這些程式碼是預先編譯後再下載到客戶端,由Silverlight CLR執行的,就理論上來說,執行效率應該比JavaScript好才對。由於Managed SLDH使用了另一種JsON格式來交換資料,所以.aspx.cs也要做一些調整。 Default.aspx.cs using System; using System.IO; using System.Data; using System.Collections.Generic; using System.Data.sqlClIEnt; using System.Configuration; using System.linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HTMLControls; using System.Xml.linq; using System.Web.Services; public partial class _Default : System.Web.UI.Page { 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[" ConnectionString" ].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; } } } private static List<object> BuildJsONRow(DaTarow row) { List<object> result = new List<object>(); List<string> columns = new List<string>(); List<object> values = new List<object>(); foreach (DataColumn col in row.table.Columns) { columns.Add(col.Columnname); values.Add(row.IsNull(col) ? string.Empty : row[col].ToString()); } result.Add(columns); result.Add(values); return result; } [WebMethod] public static List<object> GetData(int index) { Datatable table = BuildDataCache(); return BuildJsONRow(table.defaultview[index].Row); } [WebMethod] public static int GetCount() { Datatable table = BuildDataCache(); return table.defaultview.Count; } protected voID Page_Load(object sender,EventArgs e) { if (Request.queryString["ID"] != null && Request.queryString["ID"].Length > 0) { using (sqlConnection conn = new sqlConnection(ConfigurationManager.ConnectionStrings[ "ConnectionString" ].ConnectionString)) { conn.open(); sqlCommand cmd = new sqlCommand( "SELECT Photo FROM Employees WHERE EmployeeID = @ID" ,conn); cmd.Parameters.AdDWithValue("@ID",Request.queryString["ID"]); object data = cmd.ExecuteScalar(); if (data != null && ((byte[])data).Length > 0) { Response.Clear(); Response.BufferOutput = true; Response.ContentType = "image/jpeg"; MemoryStream ms = new MemoryStream(); ms.Write(((byte[])data),78,((byte[])data).Length - 78); MemoryStream jpegms = new MemoryStream(); System.Drawing.Image.FromStream(ms).Save(jpegms, System.Drawing.Imaging.ImageFormat.Jpeg); jpegms.position = 0; Response.OutputStream.Write(jpegms.GetBuffer(),(int)jpegms.Length); ms.dispose(); jpegms.dispose(); Response.Flush(); Response.End(); } } } } } |
當需要做DataBindings時,只需要在.xaml.cs的Page_Loaded事件處理函式中建立此物件即可,見下面程式碼。 Page.xaml < Canvas x:name = "parentCanvas" xmlns = "http://schemas.microsoft.com/clIEnt/2007" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" Loaded = "Page_Loaded" x:Class = "SilverlightProject1.Page;assembly=ClIEntBin/SilverlightProject1.dll" WIDth = "640" Height = "480" Background = "White" > < Canvas name = "DataDemo"Height="600"WIDth="800" Tag = "BindingContext:Default.aspx,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> < TextBlock Canvas.left = "100"Canvas.top="200" Text = "Prev"MouseleftbuttonDown="OnPrevClick"/> < TextBlock Canvas.left = "150"Canvas.top="200" Text = "Next"MouseleftbuttonDown="OnNextClick"/> Canvas> |
Page.xaml.cs using System; using System.linq; using System.Collections.Generic; using System.windows; using System.windows.Controls; using System.windows.documents; using System.windows.Ink; using System.windows.input; using System.windows.Media; using System.windows.Media.Animation; using System.windows.Shapes; namespace SilverlightProject1 { public partial class Page : Canvas { private SilverlightDataHelper.BindingContext _context = null; public voID Page_Loaded(object o,EventArgs e) { // required to initialize variables InitializeComponent(); _context = new SilverlightDataHelper.BindingContext(Findname("DataDemo") as Panel); _context.Initialize(); } voID OnPrevClick(object sender,EventArgs args) { if (_context.position > 0) { _context.position--; ((Storyboard)Findname("imgAnimation")).Begin(); } } voID OnNextClick(object sender,EventArgs args) { if (_context.position < _context.Count) { _context.position++; ((Storyboard)Findname("imgAnimation")).Begin(); } } } } |
下圖是執行畫面。 http://www.dreams.idv.tw/~code6421/files/SLDataDemo_11.zip (你需要將northwind.mdf、northwind_log.ldf複製到App_Data目錄下,或是修改web.config中的ConnectionString來連結到北風資料庫) 总结
以上是内存溢出为你收集整理的Silverlight DataBindings for 1.1 (Managed code)铪铪全部内容,希望文章能够帮你解决Silverlight DataBindings for 1.1 (Managed code)铪铪所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
评论列表(0条)