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

设计一个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;
}

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>

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

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

代码实现参考其他页面~
To be continue...
WPF学习之路(十)实例:用户注册的更多相关文章
- WPF学习之路初识
WPF学习之路初识 WPF 介绍 .NET Framework 4 .NET Framework 3.5 .NET Framework 3.0 Windows Presentation Found ...
- WPF学习之路(四)路由
路由事件概述 功能定义:路由事件是一种可以针对元素树中的多个侦听器(而不是仅针对引发该事件的对象)调用处理程序的事件. 实现定义:路由事件是一个 CLR 事件,可以由RouteEvent 类的实例提供 ...
- 【WPF学习】第二十六章 Application类——应用程序的生命周期
在WPF中,应用程序会经历简单的生命周期.在应用程序启动后,将立即创建应用程序对象,在应用程序运行时触发各种应用程序事件,你可以选择监视其中的某些事件.最后,当释放应用程序对象时,应用程序将结束. 一 ...
- WPF学习之路(十四)样式和模板
样式 实例: <Window.Resources> <Style x:Key="BtnStyle"> <Setter Property=" ...
- WPF学习之路(十二)控件(Items控件)
ListBox 提供了一个选项列表,可以固定或者动态绑定 <StackPanel> <GroupBox Margin="> <GroupBox.Header& ...
- WPF学习之路(十二)控件(Range控件)
ProgressBar 进度条,主要属性:Minimum\Maximun\Value, IsIndeterminate为True时,进度条会循环运转 <Grid> <Grid.Row ...
- WPF学习之路(十二)控件(HeaderedContent控件)
GroupBox 用来组织多种控件的常见控件,因为是内容空间,只能直接包含一项,需要使用面板一类的中间空间. Header和Content可以是任意元素 <GroupBox> <Gr ...
- WPF学习之路(十二)控件(Content控件)
Label Label相比TextBlock功能并不强大,但是支持键盘快捷键的方式获得焦点 <StackPanel> <Label Target="{Binding Ele ...
- WPF学习之路(五) 实例:写字板(续)
WordPad 2.0 上一期实现了一虽然建议但是功能比较全面的Wordpad程序,但是程序代码略显繁琐,这一期更新改进版. MainWindows.xaml 添加 <Window.Comman ...
随机推荐
- MS SQL中使用UPDATE ... INNER JOIN ...
昨天的SQL编程中,有使用到一个方法,就是把一个表某一字段更新至另一个表的字段中去. 实现这个方法,Insus.NET有尝试了几个方法,下面一一分享出来,让大家参考参考. 下面的数据只是模拟了,形式与 ...
- 基于C#的MongoDB数据库开发应用(2)--MongoDB数据库的C#开发
在上篇博客<基于C#的MongoDB数据库开发应用(1)--MongoDB数据库的基础知识和使用>里面,我总结了MongoDB数据库的一些基础信息,并在最后面部分简单介绍了数据库C#驱动的 ...
- unity3d引擎的学习
1.在project里面建立一个Editor文件夹,并在其下面放置配置某个游戏物体X的脚本,就可以在游戏物体那一栏里面新建该游戏物体X. 2.将一个游戏物体B放到某个游戏物体F下,点击Reset po ...
- C#中的枚举类型enum用法
定义一个简单的枚举类型: enum Days {Sat, Sun, Mon, Tue, Wed, Thu, Fri}; //这时候 Days.Sat = 0 ,后面依 ...
- PHP多种形式发送邮件
1. 使用 mail() 函数 没什么好讲的,就是使用系统自带的smtp系统来发送,一般是使用sendmail来发.这个按照各个系统不同而定.使用参考手册. 2. 使用管道的形式 昨天刚测试成功,使用 ...
- 【C#】VS2015开发环境的安装和配置(一)2016-08-03更新
分类:C#.VS2015.WPF.ASP.NET MVC.Android.iOS.Unity3D: 更新日期:2016-08-03 一.简介 为了避免网上乱七八糟的过时介绍,避免误导初学者,这次把至2 ...
- DatagramSocket收发UDP数据包
Java的Socket通信分为TCP和UDP两种,Socket和ServerSocket类用于TCP通信,DatagramSocket用于UDP通信. 使用DatagramSocket发送UDP数据包 ...
- spring容器加载完毕做一件事情(利用ContextRefreshedEvent事件)转
关键字:spring容器加载完毕做一件事情(利用ContextRefreshedEvent事件) 应用场景:很多时候我们想要在某个类加载完毕时干某件事情,但是使用了spring管理对象,我们这个类引用 ...
- Scalaz(41)- Free :IO Monad-Free特定版本的FP语法
我们不断地重申FP强调代码无副作用,这样才能实现编程纯代码.像通过键盘显示器进行交流.读写文件.数据库等这些IO操作都会产生副作用.那么我们是不是为了实现纯代码而放弃IO操作呢?没有IO的程序就是一段 ...
- python常用工具小函数-字符类型转换
Python3有两种表示字符序列的类型:bytes和str.前者的实例包含原始的8位值就是的字节,每个字节有8个二进制位:后者的实例包含Unicode字符.把Unicode字符转成二进制数据最常见的编 ...