你的位置:首页 > ASP.net教程

[ASP.net教程]WPF学习之路(十)实例:用户注册

通过一个注册用户的实例了解页面间数据的传递

 

首先构建一个User类  User.cs

public class User{  private string name;  public string Name  {    get { return this.name; }    set { this.name = value; }  }  private string password;  public string Password  {    get { return this.password; }    set { this.password = value; }  }  private List<string> favColors;  public List<string> FavColors  {    get { return this.favColors; }    set { this.favColors = value; }  }  public User() { }  public User(string name, string password)  {    this.name = name;    this.password = password;    favColors = new List<string>();  }  public override string ToString()  {    return "Name: {0}" + name;  }  public override bool Equals(object obj)  {    if (obj is User)    {      return (obj as User).Name.Equals(this.name) && (obj as User).Password.Equals(this.password);    }    return false;  }  public override int GetHashCode()  {    return this.name.GetHashCode();  }}

View Code

 

User信息存放在App中 App.xaml.cs

public List<User> users;private void Application_Startup(object sender, StartupEventArgs e){  users = new List<User>();  User userA = new User("UserA", "11111111");  userA.FavColors.Add("Red");  userA.FavColors.Add("Green");  users.Add(userA);  NavigationWindow win = new NavigationWindow();  win.Height = 400;  win.Width = 480;  win.Content = new LoginPage();  win.Show();}

View Code

 

设计一个LoginPage

<Page x:Class="Alex_WPFAPPDemo08.LoginPage"   ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"   ="http://schemas.microsoft.com/winfx/2006/xaml"  Title="LoginPage" WindowTitle="LoginPage" ShowsNavigationUI="False">  <Border BorderBrush="Black" BorderThickness="2" Height="150" Width="400">    <Grid>      <Grid.RowDefinitions>        <RowDefinition />        <RowDefinition />        <RowDefinition />        <RowDefinition Height="Auto"/>      </Grid.RowDefinitions>      <Grid.ColumnDefinitions>        <ColumnDefinition Width="3*"/>        <ColumnDefinition Width="7*"/>      </Grid.ColumnDefinitions>      <TextBlock Grid.Row="0" Grid.Column="0" Text="Username" Margin="5" HorizontalAlignment="Center" VerticalAlignment="Center" />      <TextBox Grid.Row="0" Grid.Column="1" Margin="5" x:Name="name"/>      <TextBlock Grid.Row="1" Grid.Column="0" Text="Password" Margin="5" HorizontalAlignment="Center" VerticalAlignment="Center" />      <PasswordBox Grid.Row="1" Grid.Column="1" Margin="5" x:Name="password"/>      <Button x:Name="btn" Grid.Row="2" Grid.Column="0" HorizontalAlignment="Right" Margin="5" Width="50" Click="Btn_Click" >        Login      </Button>      <TextBlock Grid.Row="2" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center">        <Hyperlink NavigateUri="GetPasswordPage.xaml">          Forget Password        </Hyperlink>      </TextBlock>      <TextBlock Margin="0" Grid.Row="3" Grid.ColumnSpan="2" x:Name="hyperlinkText" HorizontalAlignment="Center" VerticalAlignment="Center">        If there is no registered accounts, please click        <Hyperlink>          Register        </Hyperlink>        Page        <LineBreak />      </TextBlock>    </Grid>  </Border></Page>

View Code
private void Btn_Click(object sender, RoutedEventArgs e){  List<User> users = ((App)App.Current).users;  User user = new User(name.Text, password.Password);  if (users.Contains(user))  {    WelcomePage page = new WelcomePage(user, false);    NavigationService.Navigate(page);    return;  }  NavigationService.Navigate(new Uri("pack://application:,,,/ErrorPage.xaml"));}

View Code

 

设计一个WelcomePage

<Grid Margin="5">  <TextBlock x:Name="welcome" VerticalAlignment="Center" HorizontalAlignment="Center">  </TextBlock>  <TextBlock VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="5">      <Hyperlink NavigateUri="LoginPage.xaml">        Logout      </Hyperlink>  </TextBlock></Grid>

View Code
public WelcomePage(User user, bool isPasswordVisiable)  :this(){  welcome.Text = "Welcome " + user.Name;  if (isPasswordVisiable)    welcome.Text += "\nPassword: " + user.Password;}

View Code

Logout返回LoginPage,不保留User信息

 

设计一个ErrorPage

<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center">  <TextBlock x:Name="ErrorInfo">Login failed,</TextBlock>  please click  <Hyperlink x:Name="link" Command="NavigationCommands.BrowseBack">    here  </Hyperlink>  to return.</TextBlock>

View Code

 

 Return返回LoginPage,保留Username信息

 

 

虽然保留了Username信息,但是焦点没有停留在输入框中

创建一个依赖属性来保存最后焦点获得的元素

LoginPage.xaml.cs

public static DependencyProperty FocusElementProperty;public string FocusElement{  get { return (string)base.GetValue(LoginPage.FocusElementProperty); }  set { base.SetValue(LoginPage.FocusElementProperty, value); }}public LoginPage(){  if (LoginPage.FocusElementProperty == null)  {    LoginPage.FocusElementProperty = DependencyProperty.Register(      "FocusElement",      typeof(string),      typeof(LoginPage),      new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Journal));  }  InitializeComponent();}

View Code

PreviewLostKeyboardFocus事件记录焦点所在的文本框信息

private void Page_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e){  if (e.NewFocus == this.name || e.NewFocus == this.password)  {    this.FocusElement = (string)((DependencyObject)e.NewFocus).GetValue(FrameworkElement.NameProperty);  }}

View Code

Loaded事件根据记录信息设置焦点

private void Page_Loaded(object sender, RoutedEventArgs e){  if (this.FocusElement != null)  {    IInputElement element = (IInputElement)LogicalTreeHelper.FindLogicalNode(this, this.FocusElement);    Keyboard.Focus(element);  }}

View Code

 

设计一个RegisterPage

继承自PageFunction<T>,用于实现传递数据

<PageFunction  ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  ="http://schemas.microsoft.com/winfx/2006/xaml"  ="clr-namespace:System;assembly=mscorlib"   x:Class="Alex_WPFAPPDemo08.RegisterUserPage"  ="clr-namespace:Alex_WPFAPPDemo08"  x:TypeArguments="local:User"  ="http://schemas.open"  ="http://schemas.microsoft.com/expression/blend/2008"  mc:Ignorable="d"  d:DesignHeight="300" d:DesignWidth="300"  Title="RegisterUserPage">  <Grid>    <Grid.RowDefinitions>      <RowDefinition />      <RowDefinition />      <RowDefinition />      <RowDefinition />      <RowDefinition Height="Auto" />      <RowDefinition />    </Grid.RowDefinitions>    <Grid.ColumnDefinitions>      <ColumnDefinition />      <ColumnDefinition />      <ColumnDefinition />    </Grid.ColumnDefinitions>    <TextBlock Grid.Row="0" Grid.Column="0" VerticalAlignment="Center" Margin="5" Text="UserName" />    <TextBox Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" Margin="5" Height="20" x:Name="username" />    <TextBlock Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" Margin="5" Text="Password" />    <PasswordBox Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" Margin="5" Height="20" x:Name="password1" />    <TextBlock Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" Margin="5" Text="Confirm Password" />    <PasswordBox Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" Margin="5" Height="20" x:Name="password2" />    <TextBlock Grid.Row="3" Grid.ColumnSpan="3" Text="Security Question: What is your favourite color?" Margin="5" />    <ListBox Grid.Row="4" Grid.Column="0" Margin="5" BorderBrush="AliceBlue" BorderThickness="1" x:Name="list1">      <ListBoxItem Background="Red">Red</ListBoxItem>      <ListBoxItem Background="Blue">Blue</ListBoxItem>      <ListBoxItem Background="White">White</ListBoxItem>      <ListBoxItem Background="Green">Green</ListBoxItem>    </ListBox>    <Grid Grid.Row="4" Grid.Column="1">      <Grid.RowDefinitions>        <RowDefinition />        <RowDefinition />      </Grid.RowDefinitions>      <Button Grid.Row="0" x:Name="addBtn" Content="Add" Margin="5" Click="Add_Click" />      <Button Grid.Row="1" x:Name="removeBtn" Content="Remove" Margin="5" Click="Remove_Click" />    </Grid>    <ListBox Grid.Row="4" Grid.Column="2" Margin="5" BorderBrush="AliceBlue" BorderThickness="1" x:Name="list2" />    <WrapPanel Grid.Row="5" Grid.Column="2" HorizontalAlignment="Right">      <Button Content="Register" Click="Ok_Click" Margin="5"/>      <Button Content="Cancel" Click="Cancel_Click" Margin="5"/>    </WrapPanel>  </Grid></PageFunction>

View Code

RegisterUserPage.xaml.cs

public partial class RegisterUserPage : PageFunction<User>{private bool isLoad;public string RestoredContentState;public static DependencyProperty FocusElementProperty;public string FocusElement{  get { return (string)base.GetValue(RegisterUserPage.FocusElementProperty); }  set { base.SetValue(RegisterUserPage.FocusElementProperty, value); }}public RegisterUserPage(){  if (RegisterUserPage.FocusElementProperty == null)  {    RegisterUserPage.FocusElementProperty = DependencyProperty.Register(      "FocusElement",      typeof(string),      typeof(RegisterUserPage),      new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Journal));  }  InitializeComponent();  isLoad = true;}public RegisterUserPage(bool isLoad)  :this(){  this.isLoad = isLoad;}private void Cancel_Click(object sender, RoutedEventArgs e){  OnReturn(null);}private void Ok_Click(object sender, RoutedEventArgs e){  User user = CreateUser();  if (user == null)    return;  else  {    OnReturn(new ReturnEventArgs<User>(user));  }}private void Remove_Click(object sender, RoutedEventArgs e){  if (list2.SelectedIndex != -1)  {    NavigationService service = NavigationService.GetNavigationService(this);    string itemText = list2.SelectedItem.ToString();    string journalName = "Remove " + itemText;    service.AddBackEntry(GetJournalEntry(journalName));    list2.Items.Remove(itemText);    list1.Items.Add(itemText);  }}private void Add_Click(object sender, RoutedEventArgs e){  if (list1.SelectedIndex != -1)  {    NavigationService service = NavigationService.GetNavigationService(this);    string itemText = list1.SelectedItem.ToString();    string journalName = "Add " + itemText;    service.AddBackEntry(GetJournalEntry(journalName));    list2.Items.Add(itemText);    list1.Items.Remove(itemText);  }}private User CreateUser(){  var username = this.username.Text;  var password = this.password1.Password.Equals(this.password2.Password) ? this.password1.Password : string.Empty;  if (string.IsNullOrEmpty(password))  {    ErrorPage page = new ErrorPage();    page.ErrorInfo.Text = "The two passwords you typed do not match,";    this.NavigationService.Navigate(page);    return null;  }  User user = new User(username, password);  List<string> favColors = new List<string>();  foreach (string item in list2.Items)  {    favColors.Add(item);  }  user.FavColors = favColors;  return user;}private void Page_Loaded(object sender, RoutedEventArgs e){  if (isLoad)  {    LoadList();  }  if (this.FocusElement != null)  {    IInputElement element = (IInputElement)LogicalTreeHelper.FindLogicalNode(this, this.FocusElement);    Keyboard.Focus(element);  }}private void LoadList(){  list1.Items.Add("Red");  list1.Items.Add("Green");  list1.Items.Add("Blue");  list1.Items.Add("Yellow");  list1.Items.Add("Orange");  list1.Items.Add("Pink");  list1.Items.Add("Black");}public CustomContentState GetContentState(){  string journal;  if (!string.IsNullOrEmpty(RestoredContentState))  {    journal = RestoredContentState;  }  else  {    journal = "RegisterUserPage";  }  return GetJournalEntry(journal);}private ListSelectionJournalEntry GetJournalEntry(string journalName){  List<string> source = GetListState(list1);  List<string> target = GetListState(list2);  return new ListSelectionJournalEntry(source, target, journalName);}private List<string> GetListState(ListBox list){  List<string> items = new List<string>();  foreach (string item in list.Items)  {    items.Add(item);  }  return items;}private void Page_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e){  if (e.NewFocus == this.username)  {    this.FocusElement = (string)((DependencyObject)e.NewFocus).GetValue(FrameworkElement.NameProperty);  }  else if (e.NewFocus == this.password1 || e.NewFocus == this.password2)  {    this.FocusElement = (string)((DependencyObject)this.password1).GetValue(FrameworkElement.NameProperty);  }}

View Code

 

 

如果注册失败,导航到ErrorPage后返回,Username信息保留,其他信息丢失

采用另一种方法代替依赖属性保留页面状态,

 

构建一个类保存两个ListBox中的信息,继承自CustomContentState

[Serializable()]public class ListSelectionJournalEntry : CustomContentState{  private List<string> sourceItems;  public List<string> SourceItems  {    get { return this.sourceItems; }  }  private List<string> targetItems;  public List<string> TargetItems  {    get { return this.targetItems; }  }  private string journalEntryName;  public override string JournalEntryName  {    get    {      return journalEntryName;    }  }  public ListSelectionJournalEntry(List<string> source, List<string> target, string journalName)  {    this.sourceItems = source;    this.targetItems = target;    this.journalEntryName = journalName;  }}

View Code

 

 在GetContentState中返回一个保存两个ListBox状态的ListSelectionJournalEntry,通过AddBackEntry方法记录添加和移除按钮的事件

 

 设计一个GetPasswordPage

<Grid Margin="5">  <Grid.RowDefinitions>    <RowDefinition Height="35" />    <RowDefinition Height="35" />    <RowDefinition Height="Auto" />    <RowDefinition />    <RowDefinition />  </Grid.RowDefinitions>  <Grid.ColumnDefinitions>    <ColumnDefinition />    <ColumnDefinition />    <ColumnDefinition />  </Grid.ColumnDefinitions>  <TextBlock Text="Username" Grid.Row="0" Grid.Column="0" Margin="5" VerticalAlignment="Center" />  <TextBox x:Name="username" Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" Margin="5" VerticalAlignment="Center" Height="20"/>  <TextBlock Grid.Row="1" Grid.ColumnSpan="3" Text="Security Question: What is your favourite color?" Margin="5" />  <ListBox Grid.Row="2" Grid.Column="0" Margin="5" BorderBrush="AliceBlue" BorderThickness="1" x:Name="list1" Height="150" />  <Grid Grid.Row="2" Grid.Column="1">    <Grid.RowDefinitions>      <RowDefinition />      <RowDefinition />    </Grid.RowDefinitions>    <Button Grid.Row="0" x:Name="addBtn" Content="Add" Margin="5" Click="Add_Click" Height="30" />    <Button Grid.Row="1" x:Name="removeBtn" Content="Remove" Margin="5" Click="Remove_Click" Height="30" />  </Grid>  <ListBox Grid.Row="2" Grid.Column="2" Margin="5" BorderBrush="AliceBlue" BorderThickness="1" x:Name="list2" Height="150" />  <TextBlock Grid.Row="3" Text="Result" Margin="5" />  <Label x:Name="result" Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2" Margin="5" VerticalAlignment="Center" Height="20"/>  <Button Grid.Row="4" Grid.Column="1" Margin="5" Content="Get Password" Click="Get_Click" />  <Button Grid.Row="4" Grid.Column="2" Margin="5" Content="Return" Click="Return_Click" /></Grid>

View Code

代码实现参考其他页面~

 

 

 

 

 

 

To be continue...