Silverlight DataBindings for 1.1 (Managed code)

来源:互联网 发布:虎扑推荐的淘宝店铺 编辑:程序博客网 时间:2024/06/06 03:52
 
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, 0, 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(), 0, (int)jpegms.Length);
                    ms.Dispose();
                    jpegms.Dispose();
                    Response.Flush();
                    Response.End();
                }
            }
        }
    }
}
當需要做DataBindings時,只需要在.xaml.cs的Page_Loaded事件處理函式中建立此物件即可,見下面程式碼。
 
Page.xaml
<Canvasx: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"
        >
           <CanvasName="DataDemo"Height="600"Width="800"
 Tag="BindingContext:Default.aspx,GetData,GetCount">
                     <Canvas.Background>
                                <LinearGradientBrush>
                                           <GradientStopColor="Yellow"Offset="0.0" />
                                           <GradientStopColor="Orange"Offset="0.5" />
                                           <GradientStopColor="Red"Offset="1.0" />
                                LinearGradientBrush>
                     Canvas.Background>
           <TextBlockTag="BindingField:EmployeeID;BindingProperty:Text"
          Name="txtEmployeeID"Width="144"Height="24"Canvas.Left="166"
        Canvas.Top="23"Text="A00001"TextWrapping="Wrap"/>
                     <TextBlockTag="BindingField:LastName;BindingProperty:Text"
           Name="txtLastName"Width="320"Height="24"Canvas.Left="500"
         Canvas.Top="23"Text="Alean Company"TextWrapping="Wrap"/>
                     <TextBlockTag="BindingField:FirstName;BindingProperty:Text"Name="txtFirstName"
                      Width="320"Height="24"Canvas.Left="166"Canvas.Top="72"
                      Text="Jeffray"TextWrapping="Wrap"/>
                     <TextBlockTag="BindingField:Title;BindingProperty:Text"
                      Name="txtTitle"Width="576"Height="24"Canvas.Left="166"
                      Canvas.Top="122"Text="Taipen 101"TextWrapping="Wrap"/>
                     <TextBlockTag="BindingField:HireDate;BindingProperty:Text"Name="txtHireDate"
                      Width="576"Height="24"Canvas.Left="166"Canvas.Top="171"
                      Text="2005/3/4"TextWrapping="Wrap"/>
                     <ImageName="imgPhoto" 
Tag="BindingField:EmployeeID;BindingProperty:Source;Format:Default.aspx?ID={0}"
      Width="357"Height="206"Canvas.Left="400"Canvas.Top="301">
                                <Image.Triggers>
                                           <EventTriggerRoutedEvent="Image.Loaded">
                                                     <BeginStoryboard>
                                                                <StoryboardName="imgAnimation">
                                                                           <DoubleAnimation
                                                                           Storyboard.TargetName="imgPhoto"
                                                                           Storyboard.TargetProperty="Opacity"
                                                                           From="0.0"To="1.0"Duration="0:0:6"/>
                                                                Storyboard>
                                                     BeginStoryboard>
                                           EventTrigger>
                                Image.Triggers>
                     Image>
                     <TextBlockName="txtLabel1"Width="114"Height="24"Canvas.Left="18"
           Canvas.Top="23"Text="Employee ID:"TextWrapping="Wrap"/>
                     <TextBlockName="txtLabel1_Copy"Width="120"Height="24"Canvas.Left="349"
            Canvas.Top="23"Text="Last Name:"TextWrapping="Wrap"/>
                     <TextBlockName="txtLabel1_Copy1"Width="130"Height="24"Canvas.Left="18"
            Canvas.Top="72"Text="First Name:"TextWrapping="Wrap"/>
                     <TextBlockName="txtLabel1_Copy2"Width="104"Height="24"Canvas.Left="18"
           Canvas.Top="122"Text="Title :"TextWrapping="Wrap"/>
                     <TextBlockName="txtLabel1_Copy3"Width="93"Height="24"Canvas.Left="18"
            Canvas.Top="171"Text="Hire Date:"TextWrapping="Wrap"/>
           Canvas>
           <TextBlockCanvas.Left="100"Canvas.Top="200"
Text="Prev"MouseLeftButtonDown="OnPrevClick"/>
           <TextBlockCanvas.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來連結到北風資料庫)
 

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


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 微信账号被别人手机号冻结了怎么办 微信冻结了手机号也让人换了怎么办 顺丰快递拒收退回丢件了怎么办 京东买东西快递电话没有听到怎么办 在京东购物自己电话号输错了怎么办 北京房子卖了户口没地方迁怎么办 微信弄丢了微信密码找不到了怎么办 微信背人用过找不到密码怎么办 超市的微信支付宝收付款怎么办 办理联华超市的会员储蓄卡怎么办 卡杰文具密码本如果忘记密码怎么办 火狐浏览器阻止要访问的网页怎么办 点我达被永久停用了怎么办 刚下的软件点开系统显示停用怎么办 红酒洋酒啤酒一起喝胃不舒服怎么办 儿子13岁初一不想读书了怎么办 微信不小心点了注册新账号怎么办 在京东买东西商家不发货怎么办 在京东买东西坏了商家不退货怎么办 苯扎氯铵溶液不小心喝了一口怎么办 苯扎氯铵溶液没有稀释就用了怎么办 牛油果切开了但是没熟怎么办 手机安装程序时解析包出错怎么办 因俩人不合适分手了很难受怎么办 中考结束后成绩不好的该怎么办 在京东自营药房买药没有处方怎么办 平安普惠账号不可以注销怎么办? 京东购物非自营货没到降价了怎么办 实体店商家不承认卖的是假货怎么办 衣服上的装饰圆扣掉下来了怎么办 没在京东买东西却收到退款怎么办 小米分期付款买的手机不要了怎么办 唯品会在线支付后商品有问题怎么办 红米手机把时间删了怎么办 红米桌面上的时间删了怎么办 华为手机玩游戏老是闪退怎么办 别人家无线网距离太远信号差怎么办 微信公众号交话费交错了怎么办 手机卡里还有话费销户的话怎么办 号码忘记交话费变成空号怎么办 多屏互动没办法隔空播放怎么办?