通过一个注册用户的实例了解页面间数据的传递
首先构建一个User类 User.cs
class="code_img_closed" src="/Upload/Images/2015042211/0015B68B3C38AA5B.gif" alt="" />logs_code_hide('46f056bb-a180-42cd-8d3c-3ae83241f257',event)" src="/Upload/Images/2015042211/2B1B950FA3DF188F.gif" alt="" />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(); } }View Code
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", "11111111"); userA.FavColors.Add("Red"); userA.FavColors.Add("Green"); users.Add(userA); NavigationWindow win = new NavigationWindow(); win.Height = 400; win.Width = 480; win.Content = new LoginPage(); win.Show(); }View Code
设计一个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="2" Height="150" Width="400"> <Grid> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> <RowDefinition /> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="3*"/> <ColumnDefinition Width="7*"/> </Grid.ColumnDefinitions> <TextBlock Grid.Row="0" Grid.Column="0" Text="Username" Margin="5" HorizontalAlignment="Center" VerticalAlignment="Center" /> <TextBox Grid.Row="0" Grid.Column="1" Margin="5" x:Name="name"/> <TextBlock Grid.Row="1" Grid.Column="0" Text="Password" Margin="5" HorizontalAlignment="Center" VerticalAlignment="Center" /> <PasswordBox Grid.Row="1" Grid.Column="1" Margin="5" x:Name="password"/> <Button x:Name="btn" Grid.Row="2" Grid.Column="0" HorizontalAlignment="Right" Margin="5" Width="50" Click="Btn_Click" > Login </Button> <TextBlock Grid.Row="2" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center"> <Hyperlink NavigateUri="GetPasswordPage.xaml"> Forget Password </Hyperlink> </TextBlock> <TextBlock Margin="0" Grid.Row="3" Grid.ColumnSpan="2" x:Name="hyperlinkText" HorizontalAlignment="Center" VerticalAlignment="Center"> If there is no registered accounts, please click <Hyperlink> Register </Hyperlink> Page <LineBreak /> </TextBlock> </Grid> </Border> </Page>View Code
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")); }View Code
设计一个WelcomePage
<Grid Margin="5"> <TextBlock x:Name="welcome" VerticalAlignment="Center" HorizontalAlignment="Center"> </TextBlock> <TextBlock VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="5"> <Hyperlink NavigateUri="LoginPage.xaml"> Logout </Hyperlink> </TextBlock> </Grid>View Code
public WelcomePage(User user, bool isPasswordVisiable) :this() { welcome.Text = "Welcome " + user.Name; if (isPasswordVisiable) welcome.Text += "\nPassword: " + user.Password; }View Code
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>View Code
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(); }View Code
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); } }View Code
Loaded事件根据记录信息设置焦点
private void Page_Loaded(object sender, RoutedEventArgs e) { if (this.FocusElement != null) { IInputElement element = (IInputElement)LogicalTreeHelper.FindLogicalNode(this, this.FocusElement); Keyboard.Focus(element); } }View Code
设计一个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="300" d:DesignWidth="300" 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="0" Grid.Column="0" VerticalAlignment="Center" Margin="5" Text="UserName" /> <TextBox Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" Margin="5" Height="20" x:Name="username" /> <TextBlock Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" Margin="5" Text="Password" /> <PasswordBox Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" Margin="5" Height="20" x:Name="password1" /> <TextBlock Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" Margin="5" Text="Confirm Password" /> <PasswordBox Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" Margin="5" Height="20" x:Name="password2" /> <TextBlock Grid.Row="3" Grid.ColumnSpan="3" Text="Security Question: What is your favourite color?" Margin="5" /> <ListBox Grid.Row="4" Grid.Column="0" Margin="5" BorderBrush="AliceBlue" BorderThickness="1" 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="4" Grid.Column="1"> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <Button Grid.Row="0" x:Name="addBtn" Content="Add" Margin="5" Click="Add_Click" /> <Button Grid.Row="1" x:Name="removeBtn" Content="Remove" Margin="5" Click="Remove_Click" /> </Grid> <ListBox Grid.Row="4" Grid.Column="2" Margin="5" BorderBrush="AliceBlue" BorderThickness="1" x:Name="list2" /> <WrapPanel Grid.Row="5" Grid.Column="2" HorizontalAlignment="Right"> <Button Content="Register" Click="Ok_Click" Margin="5"/> <Button Content="Cancel" Click="Cancel_Click" Margin="5"/> </WrapPanel> </Grid> </PageFunction>View Code
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 != -1) { 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 != -1) { 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); } }View Code
如果注册失败,导航到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; } }View Code
在GetContentState中返回一个保存两个ListBox状态的ListSelectionJournalEntry,通过AddBackEntry方法记录添加和移除按钮的事件
设计一个GetPasswordPage
<Grid Margin="5"> <Grid.RowDefinitions> <RowDefinition Height="35" /> <RowDefinition Height="35" /> <RowDefinition Height="Auto" /> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <TextBlock Text="Username" Grid.Row="0" Grid.Column="0" Margin="5" VerticalAlignment="Center" /> <TextBox x:Name="username" Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" Margin="5" VerticalAlignment="Center" Height="20"/> <TextBlock Grid.Row="1" Grid.ColumnSpan="3" Text="Security Question: What is your favourite color?" Margin="5" /> <ListBox Grid.Row="2" Grid.Column="0" Margin="5" BorderBrush="AliceBlue" BorderThickness="1" x:Name="list1" Height="150" /> <Grid Grid.Row="2" Grid.Column="1"> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <Button Grid.Row="0" x:Name="addBtn" Content="Add" Margin="5" Click="Add_Click" Height="30" /> <Button Grid.Row="1" x:Name="removeBtn" Content="Remove" Margin="5" Click="Remove_Click" Height="30" /> </Grid> <ListBox Grid.Row="2" Grid.Column="2" Margin="5" BorderBrush="AliceBlue" BorderThickness="1" x:Name="list2" Height="150" /> <TextBlock Grid.Row="3" Text="Result" Margin="5" /> <Label x:Name="result" Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2" Margin="5" VerticalAlignment="Center" Height="20"/> <Button Grid.Row="4" Grid.Column="1" Margin="5" Content="Get Password" Click="Get_Click" /> <Button Grid.Row="4" Grid.Column="2" Margin="5" Content="Return" Click="Return_Click" /> </Grid>View Code
代码实现参考其他页面~
To be continue...