diff --git a/src/Intersvyaz/App.xaml.cs b/src/Intersvyaz/App.xaml.cs index fd43df0..cc7e8bd 100644 --- a/src/Intersvyaz/App.xaml.cs +++ b/src/Intersvyaz/App.xaml.cs @@ -18,6 +18,7 @@ using SimpleInjector; using Intersvyaz.Views; using Intersvyaz.Net; using Intersvyaz.Core.Services; +using Intersvyaz.ViewModels; namespace Intersvyaz { @@ -121,6 +122,7 @@ namespace Intersvyaz var container = new Container(); container.Register(Lifestyle.Singleton); container.Register(Lifestyle.Transient); + container.Register(Lifestyle.Transient); return container; } } diff --git a/src/Intersvyaz/Assets/IntersvyazLogo.png b/src/Intersvyaz/Assets/IntersvyazLogo.png new file mode 100644 index 0000000..aa80513 Binary files /dev/null and b/src/Intersvyaz/Assets/IntersvyazLogo.png differ diff --git a/src/Intersvyaz/Common/BindableBase.cs b/src/Intersvyaz/Common/BindableBase.cs new file mode 100644 index 0000000..ee2a927 --- /dev/null +++ b/src/Intersvyaz/Common/BindableBase.cs @@ -0,0 +1,41 @@ +using System.ComponentModel; +using System.Diagnostics; +using System.Runtime.CompilerServices; + +namespace Intersvyaz.Common +{ + public class BindableBase : INotifyPropertyChanged + { + /// + /// Событие об изменении значения свойства. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Установка значения в заднее поля свойства с вызовом события. + /// + /// Тип значения. + /// Заднее поле свойства. + /// Новое значение. + /// Имя свойства. (Необязательный параметр) + /// При компилиции, имя свойства будет автоматически заполнено. + protected void SetProperty(ref T back, T value, [CallerMemberName] string propertyName = null) + { + if (!Equals(back, value)) + { + back = value; + OnPropertyChanged(propertyName); + } + } + + /// + /// Вызов события об изменении + /// + /// Имя свойства. (Необязательный параметр) + /// При компилиции, имя свойства будет автоматически заполнено. + protected void OnPropertyChanged([CallerMemberName] string propertyName = null) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + } +} diff --git a/src/Intersvyaz/Common/RelayCommand.cs b/src/Intersvyaz/Common/RelayCommand.cs new file mode 100644 index 0000000..18a36f7 --- /dev/null +++ b/src/Intersvyaz/Common/RelayCommand.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Input; + +namespace Intersvyaz.Common +{ + public class RelayCommand : ICommand + { + /// + /// Действие команды. + /// + private readonly Action _execute; + + /// + /// Действие проверки «можно ли исполнить команду?». + /// + private readonly Predicate _canExecute = null; + + /// + public event EventHandler CanExecuteChanged; + + public RelayCommand(Action execute) + { + _execute = execute; + } + + public RelayCommand(Action execute, Predicate canExecute) + { + _execute = execute; + _canExecute = canExecute; + } + + /// + public bool CanExecute(object parameter) + { + return _canExecute == null || _canExecute(parameter); + } + + /// + public void Execute(object parameter) + { + _execute(parameter); + } + + /// + /// Вызов события изменения состояния. + /// + public void RaiseCanExecuteChanged() + { + CanExecuteChanged?.Invoke(this, EventArgs.Empty); + } + } +} diff --git a/src/Intersvyaz/Intersvyaz.csproj b/src/Intersvyaz/Intersvyaz.csproj index 0b9b5a0..91b3c7e 100644 --- a/src/Intersvyaz/Intersvyaz.csproj +++ b/src/Intersvyaz/Intersvyaz.csproj @@ -119,7 +119,10 @@ App.xaml + + + LoginPage.xaml @@ -131,6 +134,9 @@ + + Always + diff --git a/src/Intersvyaz/ViewModels/LoginViewModel.cs b/src/Intersvyaz/ViewModels/LoginViewModel.cs new file mode 100644 index 0000000..f7341a5 --- /dev/null +++ b/src/Intersvyaz/ViewModels/LoginViewModel.cs @@ -0,0 +1,75 @@ +using Intersvyaz.Common; +using Intersvyaz.Core.Services; +using System.Diagnostics; + +namespace Intersvyaz.ViewModels +{ + public class LoginViewModel : BindableBase + { + /// + /// Сервис сессии пользователя. + /// + private readonly ISessionService _sessionService; + + /// + /// Заднее поле имени пользователя. + /// + private string _username; + + /// + /// Заднее поле пароля пользователя. + /// + private string _password; + + /// + /// Имя пользователя. + /// + public string Username + { + get => _username; + set + { + SetProperty(ref _username, value); + LoginCommand.RaiseCanExecuteChanged(); + } + } + + /// + /// Пароль пользователя. + /// + public string Password + { + get => _password; + set + { + SetProperty(ref _password, value); + LoginCommand.RaiseCanExecuteChanged(); + } + } + + /// + /// Команда входа. + /// + public RelayCommand LoginCommand { get; } + + public LoginViewModel(ISessionService sessionService) + { + _sessionService = sessionService; + + LoginCommand = new RelayCommand(ExecuteLoginCommand, CanExecuteLoginCommand); + Username = Password = string.Empty; + } + + private async void ExecuteLoginCommand(object _) + { + var sessionData = await _sessionService.GetSessionAsync(Username, Password); + + // TODO: Обработка данных об сессии + } + + private bool CanExecuteLoginCommand(object _) + { + return !string.IsNullOrEmpty(Username) && !string.IsNullOrEmpty(Password); + } + } +} diff --git a/src/Intersvyaz/Views/LoginPage.xaml b/src/Intersvyaz/Views/LoginPage.xaml index 6cc2df0..db8a8c3 100644 --- a/src/Intersvyaz/Views/LoginPage.xaml +++ b/src/Intersvyaz/Views/LoginPage.xaml @@ -6,9 +6,37 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" - Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> + Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" + DataContext="{x:Bind ViewModel}"> - - + + + + + + + + + + + + + + +