黃忠成

風雪之閣- i live,so i writing
文章數 - 133, 回應數 - 125, 引用數 - 0


關於我:



黃忠成

  • 資深.NET 技術顧問
  • Run! PC 雜誌專欄作者
  • 程序員雜誌文章作者
  • PC Magazine 雜誌專欄作者
  • MSDN 專欄作者
  • MSDN 特約專屬講師
  • Microsoft .NET專屬講師
  • 台灣微軟特約技術顧問
  • 台灣微軟最有價值專家


  • 批評,指教,鼓勵, 請 寫信給我
    轉載文章請使用連結模式,
    請勿整篇Copy! 謝謝!


    我所提供的教育訓練:

    Windows Forms
    ASP.NET 2.0
    如有課程需要,請與我聯絡!

  • 我的著作:

  • 文章標籤

    全部標籤

    每月文章

    文章分類

    Silverlight 2 - 程式設計師與版面設計師的分工

     

    Silverlight 2 - 程式設計師與版面設計師的分工
     
     
    /黃忠成
     
     
    談真實Silverlight 2的應用程式開發
     
       從網頁應用程式時代開始,程式設計師與版面設計師間如何分工,便是一個難解的習題,程式設計師的專長是寫程式,而版面設計師的專長是做出美美的網頁,
    程式設計師多半缺乏美感,而版面設計師多半不會寫程式,專案主導者總是嘗試在兩者間找出一個合作流程,但結局多半不如預期。
     
       我們都知道,最好的情況應該是,版面設計師先將版面設計好,再交給程式設計師補上程式流程,但問題是,版面設計師由於對程式不熟悉,因此對於頁面的切換,
    按下按紐後的行為等動作難以著墨,最後這些事依然回到程式設計師身上,專案在兩者間流動是常見的事,既然流動,必然也會發生程式流程影響原來版面,或是版面
    無法在程式流程中維持不變。結局多半是,版面設計師被迫學會JavaScript+部份的ASP.NET程式,而程式設計師被迫學會小幅的版面配置美學。
     
       同樣的情況在Silverlight 2應用程式開發時也發生,先天上的架構,讓Silverlight 2應用程式開發可以分成兩個部份,一是單純XAML的畫面設計,二是事件觸發、
    資料繫結的程式撰寫,就分工上而言,單純XAML的畫面設計工作應該交給版面設計師來處理,而事件觸發、資料繫結部份則交給程式設計師。
     
    但事情並非如此順利,以一個簡單的ListBox+Item動畫來說,這原本應該是版面設計師的工作,因為Item被選取時的動畫,應該是由版面設計師所設計的,
    ListBoxItem來自資料繫結,如何讓版面設計師於Blend 2上就可以繫結資料,成了一大難題。
    另一方面,有時版面設計師會希望,當使用者將滑鼠移往某控件上時撥放一段動畫,而這段動畫自然是由版面設計師來做,但滑鼠移往某控件上然後撥放動畫,
    這卻會落到程式設計師頭上,至少!在Silverlight 2Blend 2上是如此。
     
     
    關於設計時期資料繫結
     
     Blend 2在設計Silverlight 2專案時,並不如WPF專案般允許XML資料繫結,因此要達到設計時期資料繫結動作的唯一途徑是使用CLR物件,如圖123所示。
    1
    2
    3
    當擁有資料繫結能力後,版面設計師就能在不寫半行程式碼的情況下,做出類似當滑鼠移往某個Item項目後的動畫展現,且可以立即以F5來執行看成果。
    如果搭配上程式設計師開發由ListBox繼承而來的自訂控件,那麼版面設計師能做的事就更多了。
     
    另外,值得一提的是,CLR物件取得的資料可以來自很多來源,XML或是Web Services皆可,這可讓版面設計師能於設計時期得到真實的資料,以做出趨近需求的版面。
    (PS: Blend 3 Preview提供了XML Binding機制,可讓設計師於設計時期由XML進行Binding)
     
    下面是SLDataProvider的原始碼,這是一個Silverlight Class Library專案,裡面只有一個.cs檔案(程式1),當使用Blend 2時,只須將此專案加入參考即可透過CLR物件來使用Data Binding機制。
    程式1
    using System;
    using System.Net;
    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.IO;
    using System.Collections.Generic;
     
    namespace SLDataProvider
    {
        public class Class1
        {
            private static List<string> _data = new List<string>();
     
            public List<string> Data
            {
                get
                {
                    if (_data.Count == 0)
                    {
                        try
                        {
                            System.Windows.Application.Current.Host.Source.ToString();
                            ReadServer();
                        }
                        catch (Exception)
                        {
                            ReadLocal();
                        }
                    }
                    return _data;
                }
            }
     
            private static void ReadLocal()
            {
                using (FileStream fs = new FileStream(@"C:\ttt2.txt",
                         FileMode.Open, FileAccess.Read))
                {
                    using (StreamReader sr = new StreamReader(fs))
                    {
                        while (!sr.EndOfStream)
                        {
                            _data.Add(sr.ReadLine());
                        }
                    }
                }
            }
     
            public static void ReadServer()
            {
                WebClient wc = new WebClient();
                wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
                wc.OpenReadAsync(new Uri("http://localhost:82/ttt2.txt", UriKind.Absolute));
            }
     
            static void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
            {
                _data.Clear();
                using (StreamReader sr = new StreamReader(e.Result))
                {
                    while (!sr.EndOfStream)
                    {
                        _data.Add(sr.ReadLine());
                    }
                }
            }
        }
    }
    特別注意一點,在Data的屬性存取子上,我們利用了Host.Source.ToString();來判斷目前是處於設計時期或執行時期,當這段程式碼可運行,沒有產生例外時,就是處於執行時期,
    反之則是處於設計時期,在設計時期我們直接讀取本地端的XML,反之則讀取Server端的XML。
     
    另外,由於Silverlight的網路動作皆為非同步,所以在.cs中,必須意識到此點,運用DispatcherTimer來重新設置ItemsSource屬性,如下所示:
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
     
    namespace SilverlightApplication6
    {
        public partial class Page : UserControl
        {
            public Page()
            {
                InitializeComponent();
            }
     
            private void Storyboard_Completed(object sender, EventArgs e)
            {
     
            }
     
            private void UserControl_Loaded(object sender, RoutedEventArgs e)
            {
                System.Windows.Threading.DispatcherTimer timer =
                         new System.Windows.Threading.DispatcherTimer();
                timer.Interval = TimeSpan.FromMilliseconds(1200);
                timer.Tick += new EventHandler(timer_Tick);
                timer.Start();
            }
     
            void timer_Tick(object sender, EventArgs e)
            {
                object o = lst2.ItemsSource;
                lst2.ItemsSource = null;
                lst2.ItemsSource = o as IEnumerable;
                timer.Stop();
            }
        }
    }
     
     
    PS: OK,我知道用DispatcherTimer來做很偷懶,不過我相信你會找到更好的解法,例如透過Tag或是下面的Custom Attached Properties協助,
    讓重置ItemsSource的動作變的更優雅。
     
     
    事件觸發
     
       相對於資料繫結問題,事件觸發後的動畫撥放問題就較為麻煩,就實務情況而言,能不能讓版面設計師在不寫半行程式情況下,做出當滑鼠移往控件上時撥放一段動畫,
    是能否將版面設計與程式設計完全切離的關鍵。
     
       不幸的是,Blend 2對於Silverlight 2專案的設計,並不支援Loaded外的Event Trigger,這使得版面設計師無法在不寫程式的情況下,做出前面所提到的效果,
    結局多半是版面設計師得寫上一小段程式才能完成,要達到不寫程式而完成需求,直到Silverlight 3Blend 3推出之前,都很難做到。
     
       Blend 2上,對此我的回答是Custom Attached Properties,也就是附加屬性機制,透過這個機制,我們能撰寫一個Silverlight Class Library專案,於內加入一個類別,
    然後將屬性附加到所有控件上,在使用者設定屬性值後自動掛載事件來撥放指定動畫,搭配上網路上可得到的自動XAML完成機制,可以做到未來Blend 3會提供的
    MouseOverClickEvent Trigger功能,下面是此類別的原始碼。
     
    程式3
    using System;
    using System.Net;
    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.Controls.Primitives;
    using System.Collections.Generic;
     
    namespace SLTrigger
    {
        public class Trigger
        {
            public static readonly DependencyProperty Trigger_ClickProperty =
               DependencyProperty.RegisterAttached(
                "Click",
                typeof(string),
                typeof(Trigger),
                new PropertyMetadata(
                    new PropertyChangedCallback(OnClickPropertyChanged)));
     
     
            public static readonly DependencyProperty Trigger_MouseOverProperty =
                DependencyProperty.RegisterAttached(
                "MouseOver",
                typeof(string),
                typeof(Trigger),
                new PropertyMetadata(
                    new PropertyChangedCallback(OnClickPropertyChanged)));
     
     
            public static readonly DependencyProperty Trigger_MouseLeaveProperty =
                DependencyProperty.RegisterAttached(
                "MouseLeave",
                typeof(string),
                typeof(Trigger),
                new PropertyMetadata(
                    new PropertyChangedCallback(OnClickPropertyChanged)));
     
            public static readonly DependencyProperty Trigger_LostFocusProperty =
                 DependencyProperty.RegisterAttached(
                "LostFocus",
                typeof(string),
                typeof(Trigger),
                new PropertyMetadata(
                    new PropertyChangedCallback(OnClickPropertyChanged)));
     
            public static readonly DependencyProperty Trigger_GotFocusProperty =
                DependencyProperty.RegisterAttached(
                "GotFocus",
                typeof(string),
                typeof(Trigger),
                new PropertyMetadata(
                    new PropertyChangedCallback(OnClickPropertyChanged)));
     
            public static readonly DependencyProperty Trigger_SelectionChangedProperty =
                DependencyProperty.RegisterAttached(
               "SelectionChanged",
               typeof(string),
               typeof(Trigger),
               new PropertyMetadata(
                   new PropertyChangedCallback(OnClickPropertyChanged)));
     
     
            public static readonly DependencyProperty Trigger_TargetProperty =
                DependencyProperty.RegisterAttached(
               "Target",
               typeof(string),
               typeof(Trigger),
               new PropertyMetadata(
                   new PropertyChangedCallback(OnClickPropertyChanged)));
     
     
            public static readonly DependencyProperty Trigger_ZIndexProperty =
                 DependencyProperty.RegisterAttached(
               "ZIndex",
               typeof(string),
               typeof(Trigger),
               new PropertyMetadata(
                   new PropertyChangedCallback(OnClickPropertyChanged)));
     
            public static readonly DependencyProperty Trigger_SelectedProperty =
                 DependencyProperty.RegisterAttached(
               "Selected",
               typeof(string),
               typeof(Trigger),
               new PropertyMetadata(
                   new PropertyChangedCallback(OnClickPropertyChanged)));
     
     
            private static Dictionary<object, List<object>> tempZIndex =
                    new Dictionary<object, List<object>>();
     
            private static void OnClickPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
            }
     
            private static UserControl GetUserControl(FrameworkElement start)
            {
                if (start.Parent is UserControl)
                    return start.Parent as UserControl;
                return GetUserControl((FrameworkElement)start.Parent);
            }
     
            public static void SetClick(UIElement element, string value)
            {
                if (element is ButtonBase)
                {
                    ButtonBase bb = (ButtonBase)element;
                    bb.Click -= new RoutedEventHandler(ButtonClickEvent);
                    bb.SetValue(Trigger_ClickProperty, value);
                    if (value != string.Empty && value != null)
                        bb.Click += new RoutedEventHandler(ButtonClickEvent);
                    return;
                }
                element.MouseLeftButtonUp -= new MouseButtonEventHandler(ClickEvent);
                element.SetValue(Trigger_ClickProperty, value);
                if (value != string.Empty && value != null)
                    element.MouseLeftButtonUp += new MouseButtonEventHandler(ClickEvent);
            }
     
            public static string GetClick(UIElement element)
            {
                object value = element.GetValue(Trigger_ClickProperty);
                if (value == null)
                    return string.Empty;
                return (string)value;
            }
     
            public static void SetMouseOver(UIElement element, string value)
            {
                element.MouseEnter -= new MouseEventHandler(MouseOverEvent);
                element.SetValue(Trigger_MouseOverProperty, value);
                if (value != string.Empty && value != null)
                    element.MouseEnter += new MouseEventHandler(MouseOverEvent);
            }
     
            public static string GetMouseOver(UIElement element)
            {
                object value = element.GetValue(Trigger_MouseOverProperty);
                if (value == null)
                    return string.Empty;
                return (string)value;
            }
     
            public static void SetMouseLeave(UIElement element, string value)
            {
                element.MouseEnter -= new MouseEventHandler(MouseLeaveEvent);
                element.SetValue(Trigger_MouseLeaveProperty, value);
                if (value != string.Empty && value != null)
                    element.MouseEnter += new MouseEventHandler(MouseLeaveEvent);
            }
     
            public static string GetMouseLeave(UIElement element)
            {
                object value = element.GetValue(Trigger_MouseLeaveProperty);
                if (value == null)
                    return string.Empty;
                return (string)value;
            }
     
     
            public static void SetGotFocus(UIElement element, string value)
            {
                element.GotFocus -= new RoutedEventHandler(GotFocusEvent);
                element.SetValue(Trigger_GotFocusProperty, value);
                if (value != string.Empty && value != null)
                    element.GotFocus += new RoutedEventHandler(GotFocusEvent);
            }
     
            public static string GetGotFocus(UIElement element)
            {
                object value = element.GetValue(Trigger_GotFocusProperty);
                if (value == null)
                    return string.Empty;
                return (string)value;
            }
     
            public static void SetLostFocus(UIElement element, string value)
            {
                element.LostFocus -= new RoutedEventHandler(LostFocusEvent);
                element.SetValue(Trigger_LostFocusProperty, value);
                if (value != string.Empty && value != null)
                    element.LostFocus += new RoutedEventHandler(LostFocusEvent);
            }
     
            public static string GetLostFocus(UIElement element)
            {
                object value = element.GetValue(Trigger_LostFocusProperty);
                if (value == null)
                    return string.Empty;
                return (string)value;
            }
     
     
            public static void SetZIndex(UIElement element, string value)
            {
                element.SetValue(Trigger_ZIndexProperty, value);
            }
     
            public static string GetZIndex(UIElement element)
            {
                object value = element.GetValue(Trigger_ZIndexProperty);
                if (value == null)
                    return string.Empty;
                return (string)value;
            }
     
     
            public static void SetSelected(UIElement element, string value)
            {
                element.SetValue(Trigger_SelectedProperty, value);
            }
     
            public static string GetSelected(UIElement element)
            {
                object value = element.GetValue(Trigger_SelectedProperty);
                if (value == null)
                    return string.Empty;
                return (string)value;
            }
     
            public static void SetTarget(UIElement element, string value)
            {
                element.SetValue(Trigger_TargetProperty, value);
            }
     
            public static string GetTarget(UIElement element)
            {
                object value = element.GetValue(Trigger_TargetProperty);
                if (value == null)
                    return string.Empty;
                return (string)value;
            }
     
            public static void SetSelectionChanged(UIElement element, string value)
            {
                if(element is Selector)
                {
                    Selector sel = (Selector)element;
                    sel.SelectionChanged -=
                      new SelectionChangedEventHandler(SelectionChangedEvent);
                    element.SetValue(Trigger_SelectionChangedProperty, value);
                    if (value != string.Empty && value != null)
                        sel.SelectionChanged +=
                        new SelectionChangedEventHandler(SelectionChangedEvent);
                }
                else if (element is TabControl)
                {
                    TabControl sel = (TabControl)element;
                    sel.SelectionChanged -=
                      new SelectionChangedEventHandler(SelectionChangedEvent);
                    element.SetValue(Trigger_SelectionChangedProperty, value);
                    if (value != string.Empty && value != null)
                        sel.SelectionChanged +=
                     new SelectionChangedEventHandler(SelectionChangedEvent);
                }
            }
     
            public static string GetSelectionChanged(UIElement element)
            {
                object value = element.GetValue(Trigger_SelectionChangedProperty);
                if (value == null)
                    return string.Empty;
                return (string)value;
            }
     
            public static void ButtonClickEvent(object sender, EventArgs e)
            {
                ClickEvent(sender, null);
            }
     
            public static void ClickEvent(object sender, MouseButtonEventArgs e)
            {
                string ani = GetClick(sender as UIElement);
                if (ani != string.Empty)
                {
                    UserControl uc = GetUserControl(sender as FrameworkElement);
                    Storyboard sb = uc.FindName(ani) as Storyboard;
                    Begin_Storyboard((UIElement)sender, sb);
                }
            }
     
            public static void MouseOverEvent(Object sender, MouseEventArgs e)
            {
                string ani = GetMouseOver(sender as UIElement);
                if (ani != string.Empty)
                {
                    UserControl uc = GetUserControl(sender as FrameworkElement);
                    Storyboard sb = uc.FindName(ani) as Storyboard;
                    Begin_Storyboard((UIElement)sender, sb);
                }
            }
     
            public static void MouseLeaveEvent(Object sender, MouseEventArgs e)
            {
                string ani = GetMouseLeave(sender as UIElement);
                if (ani != string.Empty)
                {
                    UserControl uc = GetUserControl(sender as FrameworkElement);
                    Storyboard sb = uc.FindName(ani) as Storyboard;
                    Begin_Storyboard((UIElement)sender, sb);
                }
            }
     
     
            public static void GotFocusEvent(Object sender, RoutedEventArgs e)
            {
                string ani = GetGotFocus(sender as UIElement);
                if (ani != string.Empty)
                {
                    UserControl uc = GetUserControl(sender as FrameworkElement);
                    Storyboard sb = uc.FindName(ani) as Storyboard;
                    Begin_Storyboard((UIElement)sender, sb);
                }
            }
     
            public static void LostFocusEvent(Object sender, RoutedEventArgs e)
            {
                string ani = GetLostFocus(sender as UIElement);
                if (ani != string.Empty)
                {
                    UserControl uc = GetUserControl(sender as FrameworkElement);
                    Storyboard sb = uc.FindName(ani) as Storyboard;
                    Begin_Storyboard((UIElement)sender, sb);
                }
            }
     
            private static void Begin_Storyboard(UIElement elem, Storyboard sb)
            {
                UserControl uc = GetUserControl(elem as FrameworkElement);
                if (sb != null)
                {
                    sb.Stop();
                    string aniTarget = GetTarget((UIElement)elem);
                    if (aniTarget != string.Empty)
                    {
                        if (aniTarget == "page")
                        {
                            UIElement aniTargetObj = uc;
                            Storyboard.SetTarget(sb, aniTargetObj);
                            string zIndex = GetZIndex(elem);
                            if (zIndex != string.Empty)
                            {
                                int oldZIndex = Canvas.GetZIndex(aniTargetObj);
                                if (!tempZIndex.ContainsKey(elem))
                                    tempZIndex.Add(sb, new List<object>()
                                     { aniTargetObj, oldZIndex });
                                Canvas.SetZIndex(aniTargetObj, int.Parse(zIndex));
                                sb.Completed -= new EventHandler(sb_Completed);
                                sb.Completed += new EventHandler(sb_Completed);
                            }
                        }
                        else
                        {
                            UIElement aniTargetObj = uc.FindName(aniTarget) as UIElement;
                            Storyboard.SetTarget(sb, aniTargetObj);
                            string zIndex = GetZIndex(elem);
                           if (zIndex != string.Empty)
                            {
                                int oldZIndex = Canvas.GetZIndex(aniTargetObj);
                                if (!tempZIndex.ContainsKey(elem))
                                    tempZIndex.Add(sb, new List<object>()
                                      { aniTargetObj, oldZIndex });
                                Canvas.SetZIndex(aniTargetObj, int.Parse(zIndex));
                                sb.Completed -= new EventHandler(sb_Completed);
                                sb.Completed += new EventHandler(sb_Completed);
                            }
                        }
                    }               
                    sb.Begin();
                }
            }
     
            static void sb_Completed(object sender, EventArgs e)
            {
                if(tempZIndex.ContainsKey(sender))
                {
                    List<object> state = tempZIndex[sender];
                    Canvas.SetZIndex((UIElement)state[0], (int)state[1]);
                    tempZIndex.Remove(sender);
                }
               
            }
     
            public static void SelectionChangedEvent(Object sender, SelectionChangedEventArgs e)
            {
                string ani = GetSelectionChanged(sender as UIElement);
                UserControl uc = GetUserControl(sender as FrameworkElement);
                if (ani != string.Empty)
                {
                    if (ani.ToLower() == "item")
                    {
                        object currentItem = null;
                        if (sender is Selector && ((Selector)sender).SelectedItem != null)
                            currentItem = ((Selector)sender).SelectedItem;
                        else if (sender is TabControl &&
                                  ((TabControl)sender).SelectedItem != null)
                            currentItem = ((TabControl)sender).SelectedItem;
     
                        string selAni = GetSelected(currentItem as UIElement);
                        if (selAni != string.Empty)
                        {
                            Storyboard sb = uc.FindName(selAni) as Storyboard;
                            string selTarget = GetTarget(currentItem as UIElement);
                            sb.Stop();
                            if (selTarget != string.Empty)
                            {
                                UIElement aniTargetObj = uc.FindName(selTarget) as UIElement;
                                Storyboard.SetTarget(sb, aniTargetObj);
                                string zIndex = GetZIndex(aniTargetObj);
                                if (zIndex != string.Empty)
                                {
                                    int oldZIndex = Canvas.GetZIndex(aniTargetObj);
                                    if (!tempZIndex.ContainsKey(aniTargetObj))
                                        tempZIndex.Add(sb, new List<object>()
                                        { aniTargetObj, oldZIndex });
                                    Canvas.SetZIndex(aniTargetObj, int.Parse(zIndex));
                                    sb.Completed -= new EventHandler(sb_Completed);
                                    sb.Completed += new EventHandler(sb_Completed);
                                }
                            }
                            else
                            {
                                Storyboard.SetTarget(sb, currentItem as UIElement);
                                string zIndex = GetZIndex(currentItem as UIElement);
                                if (zIndex != string.Empty)
                                {
                                    int oldZIndex = Canvas.GetZIndex(currentItem as UIElement);
                                    if (!tempZIndex.ContainsKey(currentItem as UIElement))
                                        tempZIndex.Add(sb, new List<object>()
                                          { currentItem as UIElement, oldZIndex });
                                    Canvas.SetZIndex(currentItem as UIElement,
                                       int.Parse(zIndex));
                                    sb.Completed -= new EventHandler(sb_Completed);
                                    sb.Completed += new EventHandler(sb_Completed);
                                }
                            }
                            sb.Begin();
                        }
                    }
                    else
                    {                   
                        Storyboard sb = uc.FindName(ani) as Storyboard;
                        if (sb != null)
                        {
                            sb.Stop();
                            string aniTarget = GetTarget((UIElement)sender);
                            if (aniTarget != string.Empty)
                            {
                                UIElement aniTargetObj = uc.FindName(aniTarget) as UIElement;
                                Storyboard.SetTarget(sb, aniTargetObj);
                                string zIndex = GetZIndex(sender as UIElement);
                                if (zIndex != string.Empty)
                                {
                                    int oldZIndex = Canvas.GetZIndex(sender as UIElement);
                                    if (!tempZIndex.ContainsKey(sender))
                                        tempZIndex.Add(sb, new List<object>()
                                        { aniTargetObj, oldZIndex });
                                    Canvas.SetZIndex(aniTargetObj, int.Parse(zIndex));
                                    sb.Completed -= new EventHandler(sb_Completed);
                                    sb.Completed += new EventHandler(sb_Completed);
                                }
                            }
                            else
                            {
                                if (sender is Selector && ((Selector)sender).SelectedItem != null)
                                {
                                    Storyboard.SetTarget(sb,
                                       ((Selector)sender).SelectedItem as DependencyObject);
                                    string zIndex = GetZIndex(sender as UIElement);
                                    if (zIndex != string.Empty)
                                    {
                                        int oldZIndex =
                              Canvas.GetZIndex(((Selector)sender).SelectedItem as UIElement);
                                        if (!tempZIndex.ContainsKey(sender))
                                            tempZIndex.Add(sb, new List<object>()
                          { ((Selector)sender).SelectedItem, oldZIndex });
                                        Canvas.SetZIndex(
                      ((Selector)sender).SelectedItem as UIElement, int.Parse(zIndex));
                                        sb.Completed -= new EventHandler(sb_Completed);
                                        sb.Completed += new EventHandler(sb_Completed);
                                    }
                                }
                                else if (sender is TabControl &&
                                       ((TabControl)sender).SelectedItem != null)
                                {
                                    Storyboard.SetTarget(sb,
                                     ((TabControl)sender).SelectedItem as DependencyObject);
                                    string zIndex = GetZIndex(sender as UIElement);
                                    int oldZIndex =
                          Canvas.GetZIndex(((Selector)sender).SelectedItem as UIElement);
                                    if (!tempZIndex.ContainsKey(sender))
                                        tempZIndex.Add(sb, new List<object>()
                                 { ((TabControl)sender).SelectedItem, oldZIndex });
                                    Canvas.SetZIndex(
                              ((Selector)sender).SelectedItem as UIElement, int.Parse(zIndex));
                                    sb.Completed -= new EventHandler(sb_Completed);
                                    sb.Completed += new EventHandler(sb_Completed);
                                }
                            }
                            sb.Begin();
                        }
                    }
                }
            }
        }
    }
    藉助此Class Library的協助,下面的XAML碼得以順利執行,不需要寫任何程式碼。
    <UserControl
               xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
               x:Class="SilverlightApplication19.Page"
               xmlns:trigger="clr-namespace:SLTrigger;assembly=SLTrigger"
               Width="640" Height="480">
               <UserControl.Resources>
                         <Storyboard x:Name="Storyboard1">
                                    <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
                                               <SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="264"/>
                                               <SplineDoubleKeyFrame KeyTime="00:00:01.2000000" Value="195"/>
                                    </DoubleAnimationUsingKeyFrames>
                                    <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">
                                               <SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="12"/>
                                               <SplineDoubleKeyFrame KeyTime="00:00:01.2000000" Value="218"/>
                                    </DoubleAnimationUsingKeyFrames>
                         </Storyboard>
               </UserControl.Resources>
     
               <Grid x:Name="LayoutRoot" Background="White">
                         <Button Height="36" trigger:Trigger.Click="Storyboard1" HorizontalAlignment="Left" Margin="180,58,0,0" VerticalAlignment="Top" Width="87" Content="Button"/>
                         <Ellipse Height="88" Margin="267,151,269,0" VerticalAlignment="Top" Stroke="#FF000000" RenderTransformOrigin="0.5,0.5" x:Name="ellipse">
                                    <Ellipse.RenderTransform>
                                               <TransformGroup>
                                                         <ScaleTransform/>
                                                         <SkewTransform/>
                                                         <RotateTransform/>
                                                         <TranslateTransform/>
                                               </TransformGroup>
                                    </Ellipse.RenderTransform>
                                    <Ellipse.Fill>
                                               <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                                         <GradientStop Color="#FF000000"/>
                                                         <GradientStop Color="#FFE2C6C6" Offset="1"/>
                                               </LinearGradientBrush>
                                    </Ellipse.Fill>
                         </Ellipse>
               </Grid>
    </UserControl>
     
     
    範例下載:
     
    SLTrigger(設計時期Event Trigger支援)
     

    DotBlogs Tags: Silverlight

    posted on 2009/6/19 02:24 | 2 人推薦 我要推薦 | 閱讀數 : 2205 | 文章分類 [ Silverlight ] 訂閱

    Feedback

    # re: Silverlight 2 - 程式設計師與版面設計師的分工 回覆

    不好意思 範例檔解壓縮解不出來
    我對這個問題很有興趣~
    不知道如果方便的話可否寄給我呢??
    2009/11/25 上午 11:56 |

    # re: Silverlight 2 - 程式設計師與版面設計師的分工 回覆

    我載了一下,解壓正常.

    2009/11/25 下午 04:16 | code6421

    回應

    標題
    姓名
    電子郵件 (將不會被顯示)
    個人網頁
    內容 
      登入後使用進階評論  
    Please add 7 and 7 and type the answer here:

    Powered by: