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 ...
随机推荐
- Web API应用架构在Winform混合框架中的应用(4)--利用代码生成工具快速开发整套应用
前面几篇介绍了Web API的基础信息,以及如何基于混合框架的方式在WInform界面里面整合了Web API的接入方式,虽然我们看似调用过程比较复杂,但是基于整个框架的支持和考虑,我们提供了代码生成 ...
- 使用DevExpress官方汉化文件对界面进行汉化的过程
在较早期的Dev开发中,基本上都是在使用一个DLL包的汉化文件,如基于13.1的汉化包文件Dxper.LocalizationCHS.Win.v13.1.5.dll,这个汉化包也比较方便,大多数时候复 ...
- Qt的tablewidget行列头自适应宽度
Qt构造一个TableWidget后,窗口最大化后,列头默认不能自适应宽度,研究了一下,Qt提供了两种方式来处理这个问题,如下: 1. 使用horizontalHeader()->setRe ...
- Java总结篇系列:类型转换/造型
Java中,经常可以遇到类型转换的场景,从变量的定义到复制.数值变量的计算到方法的参数传递.基类与派生类间的造型等,随处可见类型转换的身影.Java中的类型转换在Java编码中具有重要的作用.首先,来 ...
- PagerTabStrip及自定义的PagerTab
如图是效果图 开发中经常会用到上面是一个Tab下面是一个ViewPager(ViewPager再包含几个Fragment),当点击Tab或是滑动ViewPager,Tab及ViewPager ...
- Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
场景:eclipse中编写java中用到数组 问题: 程序不报错但是运行过程中 终止,显示字样 “ Exception in thread "main" java.lang.Arr ...
- 框架SpringMVC笔记系列 二 传值
主题:SpringMVC(第一节中再回顾复习一次) 学习资料参考网址: 1.http://www.icoolxue.com 2.http://haohaoxuexi.iteye.com/blog/13 ...
- 2014年物联网Internet of Things应用简介
body{ font: 16px/1.5em 微软雅黑,arial,verdana,helvetica,sans-serif; } 物联网(Internet of Things,缩写I ...
- Monkey测试2——Monkey测试策略
Monkey的测试策略 一. 分类 Monkey测试针对不同的对象和不同的目的采用不同的测试方案,首先测试的对象.目的及类型如下: 测试的类型分为:应用程序的稳定性测试和压力测试 测试对象分为:单一a ...
- java内存模型-锁
锁的释放-获取建立的 happens before 关系 锁是 java 并发编程中最重要的同步机制.锁除了让临界区互斥执行外,还可以让释放锁的线程向获取同一个锁的线程发送消息.下面是锁释放-获取的示 ...