WPF学习之路(十)实例:用户注册

时间:2024-01-20 17:17:45

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

首先构建一个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();
}
}

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", "");
userA.FavColors.Add("Red");
userA.FavColors.Add("Green");
users.Add(userA); NavigationWindow win = new NavigationWindow();
win.Height = ;
win.Width = ;
win.Content = new LoginPage();
win.Show();
}

设计一个LoginPage

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

WPF学习之路(十)实例:用户注册

设计一个WelcomePage

<Grid Margin="">
<TextBlock x:Name="welcome" VerticalAlignment="Center" HorizontalAlignment="Center">
</TextBlock>
<TextBlock VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="">
<Hyperlink NavigateUri="LoginPage.xaml">
Logout
</Hyperlink>
</TextBlock>
</Grid>
public WelcomePage(User user, bool isPasswordVisiable)
:this()
{
welcome.Text = "Welcome " + user.Name;
if (isPasswordVisiable)
welcome.Text += "\nPassword: " + user.Password;
}

WPF学习之路(十)实例:用户注册

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>

WPF学习之路(十)实例:用户注册

Return返回LoginPage,保留Username信息

WPF学习之路(十)实例:用户注册

虽然保留了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();
}

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);
}
}

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

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

设计一个RegisterPage

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

<PageFunction
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
x:Class="Alex_WPFAPPDemo08.RegisterUserPage"
xmlns:local="clr-namespace:Alex_WPFAPPDemo08"
x:TypeArguments="local:User"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="" d:DesignWidth=""
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="" Grid.Column="" VerticalAlignment="Center" Margin="" Text="UserName" />
<TextBox Grid.Row="" Grid.Column="" Grid.ColumnSpan="" Margin="" Height="" x:Name="username" />
<TextBlock Grid.Row="" Grid.Column="" VerticalAlignment="Center" Margin="" Text="Password" />
<PasswordBox Grid.Row="" Grid.Column="" Grid.ColumnSpan="" Margin="" Height="" x:Name="password1" />
<TextBlock Grid.Row="" Grid.Column="" VerticalAlignment="Center" Margin="" Text="Confirm Password" />
<PasswordBox Grid.Row="" Grid.Column="" Grid.ColumnSpan="" Margin="" Height="" x:Name="password2" />
<TextBlock Grid.Row="" Grid.ColumnSpan="" Text="Security Question: What is your favourite color?" Margin="" />
<ListBox Grid.Row="" Grid.Column="" Margin="" BorderBrush="AliceBlue" BorderThickness="" 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="" Grid.Column="">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Button Grid.Row="" x:Name="addBtn" Content="Add" Margin="" Click="Add_Click" />
<Button Grid.Row="" x:Name="removeBtn" Content="Remove" Margin="" Click="Remove_Click" />
</Grid>
<ListBox Grid.Row="" Grid.Column="" Margin="" BorderBrush="AliceBlue" BorderThickness="" x:Name="list2" />
<WrapPanel Grid.Row="" Grid.Column="" HorizontalAlignment="Right">
<Button Content="Register" Click="Ok_Click" Margin=""/>
<Button Content="Cancel" Click="Cancel_Click" Margin=""/>
</WrapPanel>
</Grid>
</PageFunction>

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 != -)
{
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 != -)
{
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);
}
}

WPF学习之路(十)实例:用户注册

如果注册失败,导航到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;
}
}

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

 设计一个GetPasswordPage

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

WPF学习之路(十)实例:用户注册

代码实现参考其他页面~

To be continue...