轉帖|其它|編輯:郝浩|2011-06-22 15:19:24.000|閱讀 957 次
概述:對于一個應用系統來說,登錄是最最基本的功能,也是最簡單的功能。本文就Silverlight應用的登錄表單來談談怎樣做到最佳實踐,這也是我學習Silverlight的些許沉淀。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
對于一個應用系統來說,登錄是最最基本的功能,也是最簡單的功能。本文就Silverlight應用的登錄表單來談談怎樣做到最佳實踐,這也是我學習Silverlight的些許沉淀。
想必會有朋友覺得這么簡單的功能不值得小題大做,其實非也。
首先來看下我專門為此文準備的這個Silverlight Demo的登錄表單:
一個登錄表單無非就是幾個文本框加一個登錄按鈕或取消按鈕而已。而我們都知道對于系統的登錄除了可以單擊登錄按鈕登錄之外,還需要使用回車鍵進行登錄,這基本是每一個登錄表單都具備的功能,缺一不可,如果不提供Enter鍵登錄那就大大降低了用戶體驗。
而本文所探討的則是在Silverlight應用中如何去做Enter鍵登錄。可能做ASP.NET開發的朋友很清楚,ASP.NET中登錄表單的是不需要專門寫代碼來控制Enter鍵登錄的,至于純HTML的Form等等我就不啰嗦了。對于上面這個登錄表單,先看下該表單的XAML構成(只貼出重心代碼):
<TextBlock Text="用戶名:" Grid.Row="0" Grid.Column="0"
Margin="10 20 5 0" VerticalAlignment="Center" HorizontalAlignment="Right" /> <TextBox x:Name="userNameBox"
Grid.Row="0" Grid.Column="1" Margin="0 20 0 0" Width="220"
Height="26" Text="{Binding Path=UserName,Mode=TwoWay,NotifyOnValidationError=
True, ValidatesOnExceptions=True}" TextChanged=
"userNameBox_TextChanged" SelectionChanged=
"userNameBox_SelectionChanged" /> <TextBlock Text="密碼:"
Grid.Row="1" Grid.Column="0" Margin=
"10 0 5 0" VerticalAlignment="Center" HorizontalAlignment="Right" /> <PasswordBox x:Name="userPwdBox" Grid.Row="1" Grid.Column="1"
Width="220" Height="26" Password="{Binding Path=
UserPwd,Mode=TwoWay,NotifyOnValidationError=
True,ValidatesOnExceptions=True}"
PasswordChanged="userPwdBox_PasswordChanged" />
<Button x:Name="loginBtn" Content="登錄" Grid.Row="2"
Grid.ColumnSpan="2" HorizontalAlignment=
"Right" Width="120" Height="30" Margin="0 0 30 0" Click="loginBtn_Click" />
首先,為登錄按鈕添加Click事件,實現單擊登錄按鈕進行登錄。
private void loginBtn_Click(object sender, RoutedEventArgs e)
{
UpdateBindingExpression(userNameBox, TextBox.TextProperty);
UpdateBindingExpression(userPwdBox, PasswordBox.PasswordProperty);
if (!loginValidation.HasErrors)
{
// 登錄驗證...
}
}
詳細的邏輯代碼我就省略了。這樣我們就能登錄到系統了,接下來就是本文要談的重點了。因為現在我們是不能通過輸入用戶名和密碼后敲Enter鍵登錄的,我想大家最容易想到的方法便是為userPwd這個PassWordBox添加KeyDown事件:
<PasswordBox x:Name="userPwdBox"
Grid.Row="1"
Grid.Column= "1"
Width= "220"
Height= "26"
Password= "{Binding Path=UserPwd,Mode=
TwoWay,NotifyOnValidationError=
True,ValidatesOnExceptions=True}"
PasswordChanged= "userPwdBox_PasswordChanged"
KeyDown= "userPwdBox_KeyDown" />
然后再把上面那個登錄按鈕的代碼Ctrl+C、Ctrl+V到userPwdBox_KeyDown方法體中,最后在添加點判斷敲擊的是不是Enter鍵的代碼。這樣當然可以,因為實現了文本框的Enter鍵登錄。但這樣是不是最佳的解決方案呢?當然不是,那么接下來就來看看本文所說的最佳實踐。
先談談思路吧,從上面的分析知道,既然是基本相同的代碼,那我們應該讓文本框在敲下Enter鍵的時候去觸發登錄按鈕的方法,那么就可以不必再寫同樣的代碼了。這一點應該是很容易想到的,那么怎樣實現就需要我們對Silverlight的進一步的了解了。
在Silverlight 3中,Behaviour和Trigger絕對是讓大家比較喜歡的東西了。它們允許你以聲明方式將操作關聯到事件或屬性的值。但之前,行為和觸發器需要我們安裝上 Microsoft Expression Blend SDK ,然后添加System.Windows.Interactivity.dll 程序集的引用。
目前,我們可以使用三種類型的行為: Behavour、 TriggerAction 和 TargetedTriggerAction。在這里,我們使用TargetedTriggerAction<T>泛型類,它表示操作時可以面向一個完全不同的對象,而不受其關聯的對象的影響。 它允許我們將觸發器關聯從一個對象到另一個對象,操作完全不同的元素。所以這里就特別適合了。
新建一個TextBoxEnterBehaviour類,繼承自泛型類TargetedTriggerAction<T>,泛型類型為ButtonBase,這里使用ButtonBase是因為它表示所有按鈕控件的基類,例如 Button、RepeatButton 和 HyperlinkButton,更加方便我們擴展。TextBoxEnterBehaviour類的詳細實現如下:
public class TextBoxEnterBehaviour : TargetedTriggerAction<ButtonBase>
{
private AutomationPeer peer;
private ButtonBase targetedButton;
/// <summary>
/// 在附加TargetedTriggerAction到關聯對象后發生
/// </summary>
protected override void OnAttached()
{
base.OnAttached();
targetedButton = this.Target;
if (null == targetedButton)
{
return;
}
this.peer = FrameworkElementAutomationPeer.FromElement(targetedButton);
if (this.peer == null)
{
this.peer =
FrameworkElementAutomationPeer.CreatePeerForElement(targetedButton);
}
}
/// <summary>
/// 關聯的Button改變后發生
/// </summary>
/// <param name="oldTarget"></param>
/// <param name="newTarget"></param>
protected override void OnTargetChanged
(ButtonBase oldTarget, ButtonBase newTarget)
{
base.OnTargetChanged(oldTarget, newTarget);
targetedButton = newTarget;
if (null == targetedButton)
{
return;
}
this.peer = FrameworkElementAutomationPeer.FromElement(targetedButton);
if (this.peer == null)
{
this.peer =
FrameworkElementAutomationPeer.CreatePeerForElement(targetedButton);
}
}
/// <summary>
/// 激活targeted Button并啟動targeted Button的單個明確操作
/// </summary>
/// <param name="parameter"></param>
protected override void Invoke(object parameter)
{
KeyEventArgs keyEventArgs = parameter as KeyEventArgs;
if (null != keyEventArgs && keyEventArgs.Key == Key.Enter)
{
if (null != this.peer && this.peer.IsEnabled())
{
IInvokeProvider invokeProvider =
this.peer.GetPattern(PatternInterface.Invoke) as IInvokeProvider;
invokeProvider.Invoke();
}
}
}
}
然后為userPwdBox添加觸發器。首先在該登錄表單的XAML中添加如下聲明:
xmlns:interaction="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:behaviour="clr-namespace:SLDemo" (這個為TextBoxEnterBehaviour類所在命名空間)
然后修改userPwdBox為如下代碼:
<PasswordBox x:Name="userPwdBox"
Grid.Row="1"
Grid.Column= "1"
Width= "220"
Height= "26"
Password= "{Binding Path=UserPwd,Mode=TwoWay,NotifyOnValidationError=
True,ValidatesOnExceptions=True}"
PasswordChanged= "userPwdBox_PasswordChanged">
<interaction:Interaction.Triggers>
<interaction:EventTrigger EventName="KeyDown">
<behaviour:TextBoxEnterBehaviour TargetName=
"loginBtn" /> (TargetName為關聯的登錄按鈕的Name屬性值)
</interaction:EventTrigger>
</interaction:Interaction.Triggers>
</PasswordBox>
這樣便通過很好的方法實現了Silverlight應用中的文本框回車登錄。因為這樣真正避免了重復代碼(同樣的代碼寫上3遍的話,我想你應該……你懂的,嘿嘿),又結合了Silverlight的特性,所以我稱之為最佳實踐,還請各位不要見怪呀!呵呵。
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自:www.heroicyang.com