SilverLight学习笔记--如何在xaml文件中操作用户在后台代码定义的类(2)--示例篇:创建一个登录控件(原创)(转载本文请注明出处)...
本文將示例如何運用前篇所寫知識來建立一個用戶自定義的登錄控件。此控件界面非常簡單,主要涉及的知識點是:
? 如何創建用戶控件(包括對此控件的自定義事件和屬性的編寫,此處我們將創建一個名為LoginBox和LoginButton兩個用戶控件,其中,LoginBox控件內含LoginButton控件,LoginButton控件繼承自Button控件。LoginBox和LoginButton兩個控件之間將通過自定義事件和自定義屬性進行交互)?如何創建一個用C#編寫的后臺代碼類(UserDetail.cs),并在xaml文件中操作它(實例化它的一個類對象并把它和上面創建的用戶LoginBox控件的自定義屬性(名為UserName的屬性)進行數據綁定,并在控件加載時自動顯示出來)
? 下面,進入我們的具體操作:
? 首先,我們打開VS2008,選擇新建項目,項目名命名為LoginCtrlWeb,這是我們新建的解決方案,其下有兩個項目,分別名為 LoginCtrlWeb 和 LoginCtrlWeb .Web
一、創建LoginButton控件
?在LoginCtrlWeb項目下添加一個新建類,名稱為 LoginButton.cs,此類繼承自Button類,我們將在此類中自定義一個名為OnMyBtnClick的事件。
我們知道,自定義事件通常涉及到事件的發起方和事件的接收方,通常有4個具體步驟:
(1)、在事件發起方中定義一個事件(首先聲明一個與事件相關聯的委托類型 A,然后聲明事件B,并把它和我們前面聲明的代理類A關聯起來)
(2)、在事件發起方中觸發上面定義的事件B
(3)、在事件接收方定義上述事件的事件處理程序
(4)、事件接收方向事件發起方訂閱一個事件在此代碼中,
?注意在.NET Framework中,涉及事件的各元素的命名規則如下(例如事件名為 EventName):
?? 事件傳遞參數? EventName + EventArgs
?? 事件涉及的委托類 EventName + EventHandler (object sender,EventNameEventArgs e)
?? 事件名?? OnEventName
?? 在引發事件的類中提供一個受保護的虛方法: On+EventName,防止可能存在的線程同步問題
??{
????????if(EventName?!=null)
?????????{
?????????????EventName(this.e);
??????????}
??}
?? 作為自定義事件OnMyBtnClick的發起方LoginButton,我們需要在它這里完成的工作包括:
定義一個事件OnMyBtnClick和 定義一個觸發上述事件的方法MyBtnClick,此外,我們還自定義了一個名為OnMyBtnClickEventArgs的參數類用于事件傳參,此類繼承自EventArgs類。
? 具體代碼如下:
??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?LoginCtrlWeb
{
????public?class?OnMyBtnClickEventArgs?:?EventArgs
????{??
????????//定義UserNameEventArgs類,將用于自定義事件處理函數,它的命名規則是:?EventName+EventArgs
????????private?readonly?string?_username;
????????private?readonly?string?_password;
????????public?OnMyBtnClickEventArgs(string?username,?string?password)
????????{
????????????_username?=?username;
????????????_password?=?password;
????????}
????????public?string?userName
????????{
????????????get?{?return?_username;?}
????????}
????????public?string?passWord
????????{
????????????get?{?return?_password;?}
????????}
????}
????public?class?LoginButton:Button?//用戶自定義的LoginButton類
????{
????????//首先聲明一個與事件相關聯的委托類型,它必須使用void作為返回值,同時它必須接收兩個傳入參數,一律命名為?sender?和?e
????????public?delegate?void?OnMyBtnClickEventHandler(object?sender,?OnMyBtnClickEventArgs?e);??//delegate的命名規則:?EventName+EventHandler
????????????????????????????????????????????????????????
????????//然后聲明了事件OnMyBtnClick,并把它和我們上面聲明的代理?OnMyBtnClickEventHandler?關聯起來
????????public?event?OnMyBtnClickEventHandler?OnMyBtnClick;??//事件的命名規則:
????????//聲明一個受保護的虛方法
????????protected?virtual?void?OnOnMyBtnClick(OnMyBtnClickEventArgs?e)
????????{
????????????OnMyBtnClickEventHandler?handler?=?OnMyBtnClick;??//定義一個臨時變量handler,這樣操作是防止可能存在的線程同步問題
????????????if?(handler!=null)
????????????{
????????????????handler(this,?e);
????????????}
????????}
????????//定義一個觸發事件的方法
????????public?void?MyBtnClick(string?userName,?string?passWord)
????????{
????????????//if?(OnMyBtnClick?!=?null)
????????????//{
????????????//????OnMyBtnClick(this,?new?OnMyBtnClickEventArgs(userName,?passWord));?//觸發事件,其本質就是觸發一個委托鏈
????????????//}???????????????????????????
????????????OnOnMyBtnClick(new?OnMyBtnClickEventArgs(userName,?passWord));??//調用上面定義的虛方法OnOnMyBtnClick來觸發事件
????????}
????}
}
?
? 二、創建loginBox控件。? 接下來,我們將創建loginBox控件,在此控件中,我們要用到上面創建的loginButton控件,步驟如下:
? 1、在LoginCtrlWeb項目下添加一個新建項(項目類型是:Silverlight用戶控件),此新建項命名為LoginBox.xaml,先創建它的界面:
Code
<UserControl?x:Class="LoginCtrlWeb.LoginBox"
????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"?
????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"?
????xmlns:custom="clr-namespace:LoginCtrlWeb">
????<Grid?x:Name="LayoutRoot"?Background="Chartreuse"??ShowGridLines="True"??>
????????<Grid.RowDefinitions>
????????????<RowDefinition?Height="Auto"?/>
????????????<RowDefinition?Height="Auto"?/>
????????????<RowDefinition?Height="Auto"?/>
????????????<RowDefinition?Height="Auto"?/>
????????</Grid.RowDefinitions>
????????<Grid.ColumnDefinitions>
????????????<ColumnDefinition?Width="Auto"?/>
????????????<ColumnDefinition?Width="Auto"?/>
????????</Grid.ColumnDefinitions>
????????<TextBlock?Text="用戶名"?Margin="10"?Grid.Row="0"?Grid.Column="0"?Loaded="TextBlock_Loaded"></TextBlock>
????????<TextBox?x:Name="txtUserName"?Margin="10"?Grid.Row="0"?Grid.Column="1"?Width="200"></TextBox>
????????<TextBlock?Text="密碼"?Margin="10"?Grid.Row="1"?Grid.Column="0"></TextBlock>
????????<TextBox?x:Name="txtUserPwd"?Margin="10"?Grid.Row="1"?Grid.Column="1"?Width="200"></TextBox>
?????????<custom:LoginButton?x:Name="btnLoginOK"?Grid.Row="2"?Grid.Column="1"?Height="50"?Width="100"?Content="登錄"?Margin="100,0,0,0"?Click="btnLoginOK_Click"??/>
?????????<TextBlock?x:Name="tbLoginMsg"?Grid.Row="3"??Grid.ColumnSpan="2"?Width="Auto"?Text="登錄結果提示信息欄"></TextBlock>????????
????</Grid>
</UserControl>
?由于要用到控件loginButton,所以,我們需要在xaml文件頭引用
?xmlns:custom="clr-namespace:LoginCtrlWeb"
?? 2、LoginBox.xaml.cs后臺代碼編寫
? 包括兩方面的任務,一是為loginBox自定義控件添加一個新屬性UserName,二是為LoginBox控件添加loginButton控件所傳遞過來的OnMyBtnClick事件的事件處理程序
? 首先,我們添加新屬性,代碼如下: Code
?????????public?static?DependencyProperty?UserNameProperty?=
????????????????????DependencyProperty.Register("UserName",?typeof(string),?typeof(LoginBox),?null);??//定義并注冊一個Dependency類型的屬性,用于實現在前臺的動態綁定
????????public?string?UserName
????????{
????????????get?
????????????{?
???????????????return((string)base.GetValue(UserNameProperty));
????????????}
????????????set
????????????{
????????????????base.SetValue(UserNameProperty,value);
????????????}
????????}
? 然后,我們添加OnMyBtnClick事件的事件處理程序getLoginUserInfo,此程序就是事件委托類的一個具體實例,代碼如下: Code
??????????private?void?getLoginUserInfo(object?sender,?OnMyBtnClickEventArgs?e)
????????{
????????????//聲明一個當接收到事件產生信息時,在接收方對事件進行處理的程序段
????????????if(ChekPassword(e.userName,e.passWord))
????????????{
????????????????//在此處加入如果用戶名和密碼檢查通過,則需要做的下一步處理
????????????????//我們在此處只是在輸入框下面的textBlock上顯示信息"用戶正常登錄"
????????????????this.tbLoginMsg.Text?=?"用戶??"?+?e.userName?+?"正常登錄本系統";
????????????}
????????} 其中包括另一個子程序 ChekPassword,用于對用戶名和密碼進行核對,我們在此處假設核對通過并返回true代碼如下 Code
????????????//檢查用戶名和密碼是否匹配,如果匹配則返回true,否則返回false;
????????bool?ChekPassword(string?userName,?string?passWord)
????????{
????????????//在此處添加檢查用戶名和密碼的代碼段,如果用戶名和密碼匹配則返回true
????????????return?(true);
????????}
?接下來,我們需要訂閱OnMyBtnClick 事件,并觸發事件,此段代碼我們放在loginButton控件的Click事件處理代碼中.
Code
???????private?void?btnLoginOK_Click(object?sender,?RoutedEventArgs?e)
????????{
????????????btnLoginOK.OnMyBtnClick?+=?new?LoginButton.OnMyBtnClickEventHandler(getLoginUserInfo);?//向事件發行方訂閱一個事件
????????????this.btnLoginOK.MyBtnClick(this.txtUserName.Text,?this.txtUserPwd.Text);?//觸發一個事件
????????}
? LoginBox.xaml.cs完整程序代碼如下:
Code
?using?System;
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?LoginCtrlWeb
{
????public?partial?class?LoginBox?:?UserControl
????{
????????public?static?DependencyProperty?UserNameProperty?=
????????????????????DependencyProperty.Register("UserName",?typeof(string),?typeof(LoginBox),?null);??//定義并注冊一個Dependency類型的屬性
????????public?string?UserName
????????{
????????????get?
????????????{?
???????????????return((string)base.GetValue(UserNameProperty));
????????????}
????????????set
????????????{
????????????????base.SetValue(UserNameProperty,value);
????????????}
????????}
????????public?LoginBox()
????????{
????????????InitializeComponent();
????????????
????????}
????????//檢查用戶名和密碼是否匹配,如果匹配則返回true,否則返回false;
????????bool?ChekPassword(string?userName,?string?passWord)
????????{
????????????//在此處添加檢查用戶名和密碼的代碼段,如果用戶名和密碼匹配則返回true
????????????return?(true);
????????}
????????private?void?btnLoginOK_Click(object?sender,?RoutedEventArgs?e)
????????{
????????????btnLoginOK.OnMyBtnClick?+=?new?LoginButton.OnMyBtnClickEventHandler(getLoginUserInfo);?//向事件發行方訂閱一個事件
????????????this.btnLoginOK.MyBtnClick(this.txtUserName.Text,?this.txtUserPwd.Text);?//觸發一個事件
????????}
????????private?void?getLoginUserInfo(object?sender,?OnMyBtnClickEventArgs?e)
????????{
????????????//聲明一個當接收到事件產生信息時,在接收方對事件進行處理的程序段
????????????if(ChekPassword(e.userName,e.passWord))
????????????{
????????????????//在此處加入如果用戶名和密碼檢查通過,則需要做的下一步處理
????????????????//我們在此處只是在輸入框下面的textBlock上顯示信息"用戶正常登錄"
????????????????this.tbLoginMsg.Text?=?"用戶??"?+?e.userName?+?"正常登錄本系統";
????????????}
????????}
????????private?void?TextBlock_Loaded(object?sender,?RoutedEventArgs?e)
????????{
????????????this.txtUserName.Text?=?UserName;
????????}
????}
}
? 三、在Page.xaml文件中運用我們創建的自定義控件loginBox.
?此處我們需要做如下工作:
?1、新建一個UserDetails類,代碼如下: Code
??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?LoginCtrlWeb
{
????public?class?UserDetails
????{
????????public?string?UserName?{?get;?set;?}
????}
}
2、在Page.xaml文件中初始化一個UserDetails類的實例,代碼如下 :
????<UserControl.Resources>
????????<custom:UserDetails?UserName="Jack"?x:Key="myUserDetials"/>
????</UserControl.Resources> ? 當然,我們需要在Page.xaml文件頭部加入引用
?? xmlns:custom="clr-namespace:LoginCtrlWeb"
? 這樣,我們才能真正在xaml文件中操作此類
3、在Page.xaml文件中加入我們的自定義控件loginBox Code
??????????<custom:LoginBox?x:Name="MyLoginBox"?
?????????????????????????DataContext="{StaticResource?myUserDetials}"
?????????????????????????UserName="{Binding?UserName}"?Margin="50">????????????
????????</custom:LoginBox> ?? 從代碼中我們可以看到,當我們加入我們的自定義控件loginBox時,我們對此控件的自定義屬性UserName進行了初始化賦值,賦值方式就是把它和我們定義的UserDetails類的一個實例進行綁定,而對UserDetails類所進行的初始化操作是在xmal文件中完成的。
?Page.xaml完整代碼如下: Code
?<UserControl?x:Class="LoginCtrlWeb.Page"
????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"?
????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"?
????xmlns:custom="clr-namespace:LoginCtrlWeb"
????Width="400"?Height="250">
????<UserControl.Resources>
????????<custom:UserDetails?UserName="Jack"?x:Key="myUserDetials"/>
????</UserControl.Resources>
????<StackPanel?x:Name="layoutRoot"?Background="Cornsilk">
????????<custom:LoginBox?x:Name="MyLoginBox"?
?????????????????????????DataContext="{StaticResource?myUserDetials}"
?????????????????????????UserName="{Binding?UserName}"?Margin="50">
????????????
????????</custom:LoginBox>
????</StackPanel>
</UserControl>
?? 最后,按F5測試,可看到loginBox控件在加載時就已經綁定了用戶名 Jack,點擊自定義的登錄按鈕后,在下面將顯示"用戶 Jack 正常登錄本系統"提示信息.
?? 說明:本文只重在知識點的展示,即通過本例加深對上述知識點的理解,實際操作并非如此,比如,我們對Button控件的Click事件又另定義了一個OnMyBtnClick自定義事件,并把它放入到Click事件的處理程序中進行觸發,在此處實際就是多此一舉,在我們只是通過這種操作來進行說明,實際上你可以用到本文的相關知識,加入其它事件的自定義,而不僅是Click事件的定義.
本文程序在Silverlight2.0和VS2008環境中調試通過。本文參照了部分網絡資料,希望能夠拋磚引玉,大家共同學習。
(轉載本文請注明出處)
總結
以上是生活随笔為你收集整理的SilverLight学习笔记--如何在xaml文件中操作用户在后台代码定义的类(2)--示例篇:创建一个登录控件(原创)(转载本文请注明出处)...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 合并多个Word文档
- 下一篇: Silverlight2 边学边练 之三