接觸Silverlight已經有兩三個月了,開始一直感覺他和Winform很相似,拖拖控制元件就行了,所以一直把經歷放在了研究後臺和伺服器互動和效能優化上面,很少去仔細研究Silverlight的頁面。前幾天,公司突然讓修改一個Winform的專案,再回過頭來看Winform,有種"不堪回首"的感覺。
十一長假即將來臨,在這裡先祝大家假期快樂。今天難得有空,抽出點時間研究了一下Silverlight的繼承和觸發器,拿出來和大家分享一下。Silverlight和WPF中頁面佈局使用的都是XAML,頗為相似,學習WPF的也可以參考一下。
一、Silverlight中的繼承
那麼先來說一下Silverlight中的繼承吧,我們經常在後臺程式碼中使用繼承,實現程式碼的重用。那麼在前端頁面是否可以使用繼承,實現程式碼和控制元件的重用呢?答案是可以的。通過學習繼承,我們可以更深入的理解XAML。下面來寫一個Demo,一起來看一下,首先新建一個Silverlight專案,名字就叫SLDemo吧,新增預設的網站,建完專案後目錄如下:
既然要說繼承,那麼首先要有個父類,新加一個Class,名字就叫BaseView,新增一些屬性,程式碼如下:
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; namespace SLDemo { public class BaseView : UserControl { public string Title { get; set; } public int WinWidth { get; set; } public int WinHeight { get; set; } } }
這裡簡單新增一些屬性,我們看到所有的頁面控制元件都繼承自UserControl,所以我們這個父類也要繼承UserControl,然後修改MainPage程式碼,來繼承我們這個類。
這裡要注意的是,Silverlight裡面頁面和後臺cs檔案要繼承自同一個父類,所以前端和後臺都要改,後臺cs檔案很簡單,修改後程式碼如下:
namespace SLDemo { public partial class MainPage : BaseView { public MainPage() { InitializeComponent(); } } }
只是把父類UserControl改成BaseView即可,然後來看前端頁面的修改方法:
<sld:BaseView x:Class="SLDemo.MainPage" xmlns:sld="clr-namespace:SLDemo" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="400" d:DesignWidth="600"> <Grid x:Name="LayoutRoot" Background="White"> </Grid> </sld:BaseView>
來看一下程式碼變成什麼樣了?是不是和之前大不一樣了,<Usercontrol></Usercontrol>沒有了?是不是有種"高大尚"的感覺,瞬間感覺讓人看不懂了?下面我來解釋一下:
注意看第二行,我們引入了一個名稱空間,XAML中引入名稱空間就是
xmlns:{字首}="clr-namespace:{名稱空間}"
這裡我們把字首寫成了sld(SLDemo的前三個字母),然後把Usercontrol改成我們的BaseView,和後臺cs檔案統一。實際上,XAML中應該這樣寫:
<名稱空間:類名></名稱空間:類名>
但是由於Usercontrol是系統預設的,所以前面的名稱空間就省了。接下來,先拖幾個控制元件上去看看,會發生什麼,這裡拖一個TabControl和一個Button吧,程式碼如下:
<sld:BaseView x:Class="SLDemo.MainPage" xmlns:sld="clr-namespace:SLDemo" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="400" d:DesignWidth="600" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"> <Grid x:Name="LayoutRoot" Background="White"> <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="308,119,0,0" Name="button1" VerticalAlignment="Top" Width="75" /> <sdk:TabControl Height="100" HorizontalAlignment="Left" Margin="210,205,0,0" Name="tabControl1" VerticalAlignment="Top" Width="200" /> </Grid> </sld:BaseView>
可以看到,Button和之前一樣,tabcontrol和之前還是一樣(都要引用名稱空間),這裡主要說一下名稱空間,可以看到上面多了一行程式碼:
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
這裡引入TabControl的名稱空間,看我標紅的,然後用這個字首去新增Tabcontrol,所以以後我們引用自己的自定義控制元件也是這樣,先引用命名控制元件,然後通過字首來訪問。
當然,寫了這麼多,我們還是再寫一個控制元件,其實Silverlight中Page大多用來顯示控制元件,頁面都是由控制元件堆出來的,然後在窗體顯示時,設定他的Content屬性來呈現。
到這裡,大家就可以通過繼承來重寫和擴充套件控制元件了。(今天先說到這裡,以後會詳細介紹開發自定義控制元件)。
二、Silverlight的Trigger、Action和Behavior
現在比較流行用MVVM來開發Silverlight專案,目的是實現XAML和程式碼的分離。今天就來說一下Trigger、Action和Behavior.
首先來說一下三者的關係:
Trigger : 觸發器,就像他的名字一樣,是用來監聽事件,然後執行某段程式碼
Action: 動作,就是執行一段程式碼
Behavior: 行為,看起來好像不太好理解,其實他可以看作是Trigger和Action的組合
首先來說一下Trigger和Action吧,首先來寫一個Action,新建一個類MyAction,在寫程式碼之前,我們要先引入一個名稱空間,如圖:
然後在程式碼中引用名稱空間System.Windows.Interactivity;繼承TriggerAction類,程式碼如下:
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.Interactivity; namespace SLDemo { public class MyAction : TriggerAction<DependencyObject> { protected override void Invoke(object parameter) { MessageBox.Show("你觸發了一個Action!"); } } }
這裡我們重寫了Invoke方法,讓他彈出一條訊息。下面我們來使用這個Action,讓他來響應一個事件,修改XAML程式碼如下:
<sld:BaseView x:Class="SLDemo.MainPage" xmlns:sld="clr-namespace:SLDemo" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" mc:Ignorable="d" d:DesignHeight="400" d:DesignWidth="600" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"> <Grid x:Name="LayoutRoot" Background="White"> <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="308,119,0,0" Name="button1" VerticalAlignment="Top" Width="75"> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <sld:MyAction /> </i:EventTrigger> </i:Interaction.Triggers> </Button> </Grid> </sld:BaseView>
這裡我們給一個按鈕新增了一個Trigger來偵聽單擊事件,然後繫結MyAction,執行後我們單擊按鈕,會彈出訊息框。
下面,我們來給Action傳遞一個引數,當然你可以多加幾個,我們就傳遞一個BtnName屬性吧,修改MyAction程式碼如下:
namespace SLDemo { public class MyAction : TriggerAction<DependencyObject> { public string BtnName { get; set; } protected override void Invoke(object parameter) { MessageBox.Show("你觸發了一個Action!按鈕名稱是:" + this.BtnName); } } }
我們只是新增了一個屬性,下面來看看如何使用:
執行效果如下:
我們就像平常寫XAML那樣,寫一個屬性就可以傳遞一個引數到Action裡面,當然這裡也可以繫結一個變數。但是實際開發中,我們不需要這樣做,因為我們把變數寫在ViewModel中,寫Action可以給一些Combox繫結SelectedChanged事件,目的還是實現佈局和程式碼分離。
Behavior
下面來看一下神奇的Behavior吧,有了Behavior,可以實現一些特效的重複使用,下面來寫一個簡單的例子看一下,就寫一個關於Textbox的吧,新建一個類,名字叫做TextboxBehavior,程式碼如下:
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.Interactivity; namespace SLDemo { public class TextboxBehavior : Behavior<TextBox> { protected override void OnAttached() { base.OnAttached(); AssociatedObject.TextChanged += new TextChangedEventHandler(AssociatedObject_TextChanged); } void AssociatedObject_TextChanged(object sender, TextChangedEventArgs e) { if (AssociatedObject.Text.Length < 6) { AssociatedObject.Foreground = new SolidColorBrush(Color.FromArgb(200, 255, 0, 0)); } else { AssociatedObject.Foreground = new SolidColorBrush(Color.FromArgb(200, 0, 255, 0)); } } } }
然後在XAML中新增如下程式碼:
這個時候,Textbox就繫結了我們的TextboxBehavior了,執行看下效果:
當輸入的內容小於六個字元的時候,顯示紅色
大於等於六個字元時就變成綠色。
我們一旦寫好了這個Behavior,所有頁面的Textbook都可以使用,是不是感覺很強大!原始碼已經上傳,在下面下載。