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 ...
随机推荐
- CSS代码重构与优化之路
作者:@狼狼的蓝胖子 网址:http://www.cnblogs.com/lrzw32/p/5100745.html 写CSS的同学们往往会体会到,随着项目规模的增加,项目中的CSS代码也会越来越多, ...
- ajaxfileupload asp.net 的简单使用
本人菜鸟,第一次写博客,不会排版,只是记录工作中常用的东西 ajaxfileupload.js源码: http://www.rczjp.cn/HTML/110420/20113620053635.ht ...
- C#中使用Sql对Excel条件查询
如何在C#中实现对Excel的条件查询呢? 在使用Sql条件语句对Excel进行查询时,遇到"至少一个参数没有被指定值"的问题,如何解决? 使用OleDbConnection对象创 ...
- 第一讲:WCF介绍
代码 https://yunpan.cn/cPns5DkGnRGNs 密码:3913 ...
- java.lang.NoSuchMethodError: org.apache.xerces.impl.xs.XMLSchemaLoader.loadGrammar
今天在服务器部署的时候,发生了这个问题,明明在本机上使用的时候,没有发生错误,但是发布到服务器上的时候却发生了这个错误,百度了好久,发现遇到这个问题的人很多,但是却没有一个比较满意的答案,后来还是通过 ...
- c++之string.find(string)
先来看一个例子吧: #include "iostream" #include "string" using namespace std; // 定义函数求str ...
- Markdown生成左边框目录
自从接触了Markdown后就一直用这种语言写学习笔记. 但是一直在纠结如何生成方便的目录. 下面是我搞得一个简单的模板可以生成固定在屏幕左边的目录. 就是这种 第一步,编辑器 首先,需要一个可以自动 ...
- 初识Aop和扩展Aop
一.什么叫做AOp 解析:Aop(Aspect Oriented Programming)是面向切面编程,软件编程的一种思想. OOp(Object Oriented Programming)是面向对 ...
- texrecon进行纹理映射
使用texrecon进行纹理映射: 1) 跳转到mesh所在目录 cd meshdir 2) 参数 a) texrecon.exe b) bun ...
- Trumbowyg - 轻量的 WYSIWYG 编辑器
Trumbowyg 是一个轻量,可定制的 jQuery 所见即所得(WYSIWYG)的编辑器插件.美丽的设计,生成语义化代码,带有功能强大的 API .编辑器和生成的代码进行了优化以支持 HTML5. ...