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 ...
随机推荐
- 参考例子,学习Func<T, TResult>委托
这些天,开发ASP.NET MVC,其间有查找资料,发现一个全新的Func<T, TResult> 委托.让我们在开发时,节省与简化很多. 在开发过程中,我们需要把一个泛型List< ...
- grep命令的使用
grep是UNIX和LINUX中使用最广泛的命令之一.grep允许对文本文件进行模式查找.如果找到匹配模式, grep打印包含模式的所有行.grep支持基本正则表达式,也支持其扩展集.grep有三种变 ...
- C#编程总结(四)多线程应用
C#编程总结(四)多线程应用 多线程应用很广泛,简单总结了一下: 1)不阻断主线程,实现即时响应,由后台线程完成特定操作2)多个线程,完成同类任务,提高并发性能3)一个任务有多个独立的步骤,多个线程并 ...
- FreeBSD应该装gnome3做桌面
目前freebsd pkg包管理体系的repo源多了一些,速度快了很多. 仓库中目前的版本为3.14,安装gnome3很简单. pkg install xorg gnome3 echo "e ...
- 【算法和数据结构】_11_小算法_itoa、ftoa及字符串倒置
[1]main.c /**************************************************** * * 把整数按照进制数转换为相应进制的字符串 *(要考虑符号),比如 ...
- Scalaz(38)- Free :Coproduct-Monadic语句组合
很多函数式编程爱好者都把FP称为Monadic Programming,意思是用Monad进行编程.我想FP作为一种比较成熟的编程模式,应该有一套比较规范的操作模式吧.因为Free能把任何F[A]升格 ...
- 利用Canvas编辑图片
使用<canvas>对象在浏览器中把一幅彩色图片变成灰度图片. grayscale.html <!DOCTYPE html> <html lang="en&qu ...
- 减小服务器负担,Apache启用mod_expires模块
mod_expires可以减少10%左右的重复请求,让重复的用户对指定的页面请求结果都CACHE在本地,根本不向服务器发出请求. 在使用之前,首先要确认一下”mod_expires”模组是否有启用.如 ...
- reset
html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, ...
- Glide.js:响应式 & 触摸友好的 jQuery 滑块插件
Glide.js 是一款响应式和对触摸友好的 jQuery 滑块.基于 CSS3 转换实现,并在低版本浏览器降级处理.Glide.js 简单,重量轻,快速,适用于智能手机,平板电脑和台式机.它支持 s ...