Saya telah menyiapkan proyek pengujian kecil dan membuat halaman login yang menggunakan nama pengguna dan kata sandi. Saya menggunakan pendekatan MVVM dan kerangka Prism. Saya mengikuti video ini (https://www.youtube.com/watch?v=ZfBy2nfykqY).
Ini xamlnya:
<Page x:Class="Control_Center.Views.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Control_Center.Views"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel VerticalAlignment="Center"
HorizontalAlignment="Center"
Grid.Row="0">
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center">
<TextBlock Name="LoginResponse"
Text="{Binding LoginStatus}" />
</StackPanel>
</StackPanel>
<StackPanel VerticalAlignment="Center"
HorizontalAlignment="Center"
Grid.Row="1">
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center">
<TextBox Name="UsernameBox"
Text="{Binding Username, UpdateSourceTrigger=PropertyChanged}"
AcceptsReturn="False"
PlaceholderText="Username..."
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="14"
Width="200"
Height="25" />
</StackPanel>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Center">
<PasswordBox Name="PasswordBox"
PasswordRevealMode="Peek"
PlaceholderText="Password..."
Width="200"
Height="25"
VerticalAlignment="Center"
HorizontalAlignment="Center"
FontSize="14"
PasswordChanged="PasswordBox_PasswordChanged" />
</StackPanel>
<StackPanel Orientation="Horizontal"
HorizontalAlignment="Right">
<Button Name="LoginButton"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Margin="0,10,0,0"
FontSize="12"
Content="Login"
Command="{Binding LoginCommand}" />
<Button Name="CancelButton"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Margin="10,10,0,0"
FontSize="12"
Content="Cancel" />
</StackPanel>
</StackPanel>
</Grid>
</Page>
Dan viewModel (Catatan: BindableBase adalah bagian dari Prism: https://github.com/PrismLibrary/Prism/blob/master/Source/Prism/Mvvm/BindableBase.cs):
using System;
using System.Diagnostics;
using System.Windows.Input;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Prism.Commands;
using Prism.Mvvm;
namespace EJD_Control_Center.ViewModels
{
class ViewLoginViewModel : BindableBase
{
private string _username;
public string Username
{
get { return _username; }
set { SetProperty(ref _username, value); }
}
private string _password;
public string Password
{
get { return _password; }
set { SetProperty(ref _password, value); }
}
private string _loginStatus;
public string LoginStatus
{
get { return _loginStatus; }
set { SetProperty(ref _loginStatus, value); }
}
public DelegateCommand LoginCommand { get; set; }
public ViewLoginViewModel()
{
LoginCommand = new DelegateCommand(Execute, CanExecute).ObservesProperty(() => Username).ObservesProperty(() => Password);
}
private bool CanExecute()
{
Debug.WriteLine($"Username: {Username}, password: {Password}");
Debug.WriteLine("Username is not null or whitespace? " + !string.IsNullOrWhiteSpace(Username) + ", and password: " + !string.IsNullOrWhiteSpace(Password));
return !string.IsNullOrWhiteSpace(Username) && !string.IsNullOrWhiteSpace(Password);
}
private void Execute()
{
LoginStatus = $"Login Successful! Username: {Username} Password: {Password}";
//actually return the status of the login request, but we don't have this yet. then switch screens.
}
}
}
Dan untuk penyelesaiannya, kode di belakang:
using Windows.Foundation;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Control_Center.ViewModels;
namespace Control_Center.Views
{
/// <summary>
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
InitializeComponent();
ApplicationView.PreferredLaunchViewSize = new Size(500, 320);
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;
DataContext = new ViewLoginViewModel();
}
private void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e)
{
var vm = (ViewLoginViewModel) DataContext;
vm.Password = PasswordBox.Password;
}
}
}
Sekarang sebelum ada yang memulai, saya tahu ini bukan cara yang aman untuk menangani penyampaian kata sandi. Bukan itu inti pertanyaan ini.
Masalahnya adalah ketika saya mengikat kotak teks nama pengguna ke variabel Nama Pengguna di ViewModel sepertinya tidak memperbarui String itu. Jika saya menyetel nama pengguna di ViewModel menjadi sesuatu, katakanlah "test", itu akan menampilkannya di kotak teks tetapi tidak ada pembaruan pada kotak teks itu yang mengubah variabel Nama Pengguna di ViewModel.
Output yang saya dapatkan ketika memodifikasi kedua kotak tersebut adalah:
Username: , password: d
Username is not null or whitespace? False, and password: True
Bahkan ketika kotak teks nama pengguna memiliki sesuatu di dalamnya. Satu-satunya alasan baris debug tersebut muncul adalah cara saya menangani kata sandi dengan memanggil canExecute, tetapi cara saya menangani nama pengguna tidak meskipun sejauh yang saya pahami seharusnya demikian.
Mengapa "{Binding Username, UpdateSourceTrigger=PropertyChanged}"
tidak mengirimkan teks kotak teks nama pengguna ke variabel nama pengguna di ViewModel?