zoukankan      html  css  js  c++  java
  • 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();
        }
    }
    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 += "
    Password: " + 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...

  • 相关阅读:
    音乐播放器
    对象的单体模式和面向对象
    箭头函数详解及this指向
    ES6的基础语法
    房贷灵活计算器
    [译文] SQL JOIN,你想知道的应该都有
    [Perl] 删除数组中重复元素
    [Qt] 自定义 滚动条 样式
    nodejs之异步思想
    导致人生失败的31种原因(转自csdn博客)
  • 原文地址:https://www.cnblogs.com/alex09/p/4442261.html
Copyright © 2011-2022 走看看