mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-26 07:47:54 +01:00
Add Community Toolkit example
This commit is contained in:
19
CommunityToolkitExample/CommunityToolkitExample.csproj
Normal file
19
CommunityToolkitExample/CommunityToolkitExample.csproj
Normal file
@@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Terminal.Gui\Terminal.Gui.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
7
CommunityToolkitExample/LoginAction.cs
Normal file
7
CommunityToolkitExample/LoginAction.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace CommunityToolkitExample;
|
||||
|
||||
internal enum LoginAction
|
||||
{
|
||||
Validation,
|
||||
LoginProgress
|
||||
}
|
||||
62
CommunityToolkitExample/LoginView.Designer.cs
generated
Normal file
62
CommunityToolkitExample/LoginView.Designer.cs
generated
Normal file
@@ -0,0 +1,62 @@
|
||||
using Terminal.Gui;
|
||||
|
||||
namespace CommunityToolkitExample;
|
||||
|
||||
internal partial class LoginView : Window
|
||||
{
|
||||
private Label titleLabel;
|
||||
private Label usernameLengthLabel;
|
||||
private TextField usernameInput;
|
||||
private Label passwordLengthLabel;
|
||||
private TextField passwordInput;
|
||||
private Label validationLabel;
|
||||
private Button loginButton;
|
||||
private Button clearButton;
|
||||
private Label loginProgressLabel;
|
||||
|
||||
private void InitializeComponent ()
|
||||
{
|
||||
titleLabel = new Label ();
|
||||
titleLabel.Text = "Login Form";
|
||||
Add (titleLabel);
|
||||
usernameLengthLabel = new Label ();
|
||||
usernameLengthLabel.X = Pos.Left (titleLabel);
|
||||
usernameLengthLabel.Y = Pos.Top (titleLabel) + 1;
|
||||
Add (usernameLengthLabel);
|
||||
usernameInput = new TextField ();
|
||||
usernameInput.X = Pos.Right (usernameLengthLabel) + 1;
|
||||
usernameInput.Y = Pos.Top (usernameLengthLabel);
|
||||
usernameInput.Width = 40;
|
||||
Add (usernameInput);
|
||||
passwordLengthLabel = new Label ();
|
||||
passwordLengthLabel.X = Pos.Left (usernameLengthLabel);
|
||||
passwordLengthLabel.Y = Pos.Top (usernameLengthLabel) + 1;
|
||||
Add (passwordLengthLabel);
|
||||
passwordInput = new TextField ();
|
||||
passwordInput.X = Pos.Right (passwordLengthLabel) + 1;
|
||||
passwordInput.Y = Pos.Top (passwordLengthLabel);
|
||||
passwordInput.Width = 40;
|
||||
passwordInput.Secret = true;
|
||||
Add (passwordInput);
|
||||
validationLabel = new Label ();
|
||||
validationLabel.X = Pos.Left (passwordInput);
|
||||
validationLabel.Y = Pos.Top (passwordInput) + 1;
|
||||
Add (validationLabel);
|
||||
loginButton = new Button ();
|
||||
loginButton.X = Pos.Left (validationLabel);
|
||||
loginButton.Y = Pos.Top (validationLabel) + 1;
|
||||
loginButton.Text = "_Login";
|
||||
Add (loginButton);
|
||||
clearButton = new Button ();
|
||||
clearButton.X = Pos.Left (loginButton);
|
||||
clearButton.Y = Pos.Top (loginButton) + 1;
|
||||
clearButton.Text = "_Clear";
|
||||
Add (clearButton);
|
||||
loginProgressLabel = new Label ();
|
||||
loginProgressLabel.X = Pos.Left (clearButton);
|
||||
loginProgressLabel.Y = Pos.Top (clearButton) + 1;
|
||||
loginProgressLabel.Width = 40;
|
||||
loginProgressLabel.Height = 1;
|
||||
Add (loginProgressLabel);
|
||||
}
|
||||
}
|
||||
68
CommunityToolkitExample/LoginView.cs
Normal file
68
CommunityToolkitExample/LoginView.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Terminal.Gui;
|
||||
|
||||
namespace CommunityToolkitExample;
|
||||
|
||||
internal partial class LoginView : IRecipient<Message<LoginAction>>
|
||||
{
|
||||
public LoginView (LoginViewModel viewModel)
|
||||
{
|
||||
WeakReferenceMessenger.Default.Register (this);
|
||||
Title = $"Community Toolkit MVVM Example - {Application.QuitKey} to Exit";
|
||||
ViewModel = viewModel;
|
||||
InitializeComponent ();
|
||||
usernameInput.TextChanged += (_, _) =>
|
||||
{
|
||||
ViewModel.Username = usernameInput.Text;
|
||||
SetText ();
|
||||
};
|
||||
passwordInput.TextChanged += (_, _) =>
|
||||
{
|
||||
ViewModel.Password = passwordInput.Text;
|
||||
SetText ();
|
||||
};
|
||||
loginButton.Accept += (_, _) =>
|
||||
{
|
||||
if (!ViewModel.CanLogin) { return; }
|
||||
ViewModel.LoginCommand.Execute (null);
|
||||
};
|
||||
|
||||
clearButton.Accept += (_, _) =>
|
||||
{
|
||||
ViewModel.ClearCommand.Execute (null);
|
||||
SetText ();
|
||||
};
|
||||
|
||||
Initialized += (_, _) => { ViewModel.Initialized (); };
|
||||
}
|
||||
|
||||
public LoginViewModel ViewModel { get; set; }
|
||||
|
||||
public void Receive (Message<LoginAction> message)
|
||||
{
|
||||
switch (message.Value)
|
||||
{
|
||||
case LoginAction.LoginProgress:
|
||||
{
|
||||
loginProgressLabel.Text = ViewModel.LoginProgressMessage;
|
||||
break;
|
||||
}
|
||||
case LoginAction.Validation:
|
||||
{
|
||||
validationLabel.Text = ViewModel.ValidationMessage;
|
||||
validationLabel.ColorScheme = ViewModel.ValidationColorScheme;
|
||||
break;
|
||||
}
|
||||
}
|
||||
SetText();
|
||||
Application.Refresh ();
|
||||
}
|
||||
|
||||
private void SetText ()
|
||||
{
|
||||
usernameInput.Text = ViewModel.Username;
|
||||
usernameLengthLabel.Text = ViewModel.UsernameLengthMessage;
|
||||
passwordInput.Text = ViewModel.Password;
|
||||
passwordLengthLabel.Text = ViewModel.PasswordLengthMessage;
|
||||
}
|
||||
}
|
||||
118
CommunityToolkitExample/LoginViewModel.cs
Normal file
118
CommunityToolkitExample/LoginViewModel.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Terminal.Gui;
|
||||
|
||||
namespace CommunityToolkitExample;
|
||||
|
||||
internal partial class LoginViewModel : ObservableObject
|
||||
{
|
||||
private const string DEFAULT_LOGIN_PROGRESS_MESSAGE = "Press 'Login' to log in.";
|
||||
private const string LOGGING_IN_PROGRESS_MESSAGE = "Logging in...";
|
||||
private const string VALID_LOGIN_MESSAGE = "The input is valid!";
|
||||
private const string INVALID_LOGIN_MESSAGE = "Please enter a valid user name and password.";
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _canLogin;
|
||||
|
||||
private string _password;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _passwordLengthMessage;
|
||||
|
||||
private string _username;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _usernameLengthMessage;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _loginProgressMessage;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _validationMessage;
|
||||
|
||||
[ObservableProperty]
|
||||
private ColorScheme? _validationColorScheme;
|
||||
|
||||
public LoginViewModel ()
|
||||
{
|
||||
Username = string.Empty;
|
||||
Password = string.Empty;
|
||||
|
||||
ClearCommand = new (Clear);
|
||||
LoginCommand = new (Execute);
|
||||
|
||||
Clear ();
|
||||
|
||||
return;
|
||||
|
||||
async void Execute () { await Login (); }
|
||||
}
|
||||
|
||||
public RelayCommand ClearCommand { get; }
|
||||
|
||||
public RelayCommand LoginCommand { get; }
|
||||
|
||||
public string Password
|
||||
{
|
||||
get => _password;
|
||||
set
|
||||
{
|
||||
SetProperty (ref _password, value);
|
||||
PasswordLengthMessage = $"_Password ({_password.Length} characters):";
|
||||
ValidateLogin ();
|
||||
}
|
||||
}
|
||||
|
||||
private void ValidateLogin ()
|
||||
{
|
||||
CanLogin = !string.IsNullOrEmpty (Username) && !string.IsNullOrEmpty (Password);
|
||||
SendMessage (LoginAction.Validation);
|
||||
}
|
||||
|
||||
public string Username
|
||||
{
|
||||
get => _username;
|
||||
set
|
||||
{
|
||||
SetProperty (ref _username, value);
|
||||
UsernameLengthMessage = $"_Username ({_username.Length} characters):";
|
||||
ValidateLogin ();
|
||||
}
|
||||
}
|
||||
|
||||
private void Clear ()
|
||||
{
|
||||
Username = string.Empty;
|
||||
Password = string.Empty;
|
||||
SendMessage (LoginAction.Validation);
|
||||
SendMessage (LoginAction.LoginProgress, DEFAULT_LOGIN_PROGRESS_MESSAGE);
|
||||
}
|
||||
|
||||
private async Task Login ()
|
||||
{
|
||||
SendMessage (LoginAction.LoginProgress, LOGGING_IN_PROGRESS_MESSAGE);
|
||||
await Task.Delay (TimeSpan.FromSeconds (1));
|
||||
Clear ();
|
||||
}
|
||||
|
||||
private void SendMessage (LoginAction loginAction, string message = "")
|
||||
{
|
||||
switch (loginAction)
|
||||
{
|
||||
case LoginAction.LoginProgress:
|
||||
LoginProgressMessage = message;
|
||||
break;
|
||||
case LoginAction.Validation:
|
||||
ValidationMessage = CanLogin ? VALID_LOGIN_MESSAGE : INVALID_LOGIN_MESSAGE;
|
||||
ValidationColorScheme = CanLogin ? Colors.ColorSchemes ["Base"] : Colors.ColorSchemes ["Error"];
|
||||
break;
|
||||
}
|
||||
WeakReferenceMessenger.Default.Send (new Message<LoginAction> { Value = loginAction });
|
||||
}
|
||||
|
||||
public void Initialized ()
|
||||
{
|
||||
Clear ();
|
||||
}
|
||||
}
|
||||
6
CommunityToolkitExample/Message.cs
Normal file
6
CommunityToolkitExample/Message.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace CommunityToolkitExample;
|
||||
|
||||
internal class Message<T>
|
||||
{
|
||||
public T Value { get; set; }
|
||||
}
|
||||
25
CommunityToolkitExample/Program.cs
Normal file
25
CommunityToolkitExample/Program.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Terminal.Gui;
|
||||
|
||||
namespace CommunityToolkitExample;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public static IServiceProvider Services { get; private set; }
|
||||
|
||||
private static void Main (string [] args)
|
||||
{
|
||||
Services = ConfigureServices ();
|
||||
Application.Init ();
|
||||
Application.Run (Services.GetRequiredService<LoginView> ());
|
||||
Application.Shutdown ();
|
||||
}
|
||||
|
||||
private static IServiceProvider ConfigureServices ()
|
||||
{
|
||||
var services = new ServiceCollection ();
|
||||
services.AddTransient<LoginView> ();
|
||||
services.AddTransient<LoginViewModel> ();
|
||||
return services.BuildServiceProvider ();
|
||||
}
|
||||
}
|
||||
32
Terminal.sln
32
Terminal.sln
@@ -38,12 +38,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Terminal.Gui.Analyzers.Inte
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Terminal.Gui.Analyzers.Internal.Debugging", "Analyzers\Terminal.Gui.Analyzers.Internal.Debugging\Terminal.Gui.Analyzers.Internal.Debugging.csproj", "{C2AD09BD-D579-45A7-ACA3-E4EF3BC027D2}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityToolkitExample", "CommunityToolkitExample\CommunityToolkitExample.csproj", "{58FDCA8F-08F7-4D80-9DA3-6A9AED01E163}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{5DE91722-8765-4E2B-97E4-2A18010B5CED} = {CCADA0BC-61CF-4B4B-96BA-A3B0C0A7F54D}
|
||||
{715DB4BA-F989-4DF6-B46F-5ED26A32B2DD} = {CCADA0BC-61CF-4B4B-96BA-A3B0C0A7F54D}
|
||||
{C2AD09BD-D579-45A7-ACA3-E4EF3BC027D2} = {CCADA0BC-61CF-4B4B-96BA-A3B0C0A7F54D}
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
@@ -53,14 +50,6 @@ Global
|
||||
{00F366F8-DEE4-482C-B9FD-6DB0200B79E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{00F366F8-DEE4-482C-B9FD-6DB0200B79E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{00F366F8-DEE4-482C-B9FD-6DB0200B79E5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5DE91722-8765-4E2B-97E4-2A18010B5CED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5DE91722-8765-4E2B-97E4-2A18010B5CED}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5DE91722-8765-4E2B-97E4-2A18010B5CED}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5DE91722-8765-4E2B-97E4-2A18010B5CED}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{715DB4BA-F989-4DF6-B46F-5ED26A32B2DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{715DB4BA-F989-4DF6-B46F-5ED26A32B2DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{715DB4BA-F989-4DF6-B46F-5ED26A32B2DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{715DB4BA-F989-4DF6-B46F-5ED26A32B2DD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{88979F89-9A42-448F-AE3E-3060145F6375}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{88979F89-9A42-448F-AE3E-3060145F6375}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{88979F89-9A42-448F-AE3E-3060145F6375}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@@ -77,14 +66,31 @@ Global
|
||||
{B0A602CD-E176-449D-8663-64238D54F857}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B0A602CD-E176-449D-8663-64238D54F857}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B0A602CD-E176-449D-8663-64238D54F857}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5DE91722-8765-4E2B-97E4-2A18010B5CED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5DE91722-8765-4E2B-97E4-2A18010B5CED}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5DE91722-8765-4E2B-97E4-2A18010B5CED}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5DE91722-8765-4E2B-97E4-2A18010B5CED}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{715DB4BA-F989-4DF6-B46F-5ED26A32B2DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{715DB4BA-F989-4DF6-B46F-5ED26A32B2DD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{715DB4BA-F989-4DF6-B46F-5ED26A32B2DD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{715DB4BA-F989-4DF6-B46F-5ED26A32B2DD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C2AD09BD-D579-45A7-ACA3-E4EF3BC027D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C2AD09BD-D579-45A7-ACA3-E4EF3BC027D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C2AD09BD-D579-45A7-ACA3-E4EF3BC027D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C2AD09BD-D579-45A7-ACA3-E4EF3BC027D2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{58FDCA8F-08F7-4D80-9DA3-6A9AED01E163}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{58FDCA8F-08F7-4D80-9DA3-6A9AED01E163}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{58FDCA8F-08F7-4D80-9DA3-6A9AED01E163}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{58FDCA8F-08F7-4D80-9DA3-6A9AED01E163}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{5DE91722-8765-4E2B-97E4-2A18010B5CED} = {CCADA0BC-61CF-4B4B-96BA-A3B0C0A7F54D}
|
||||
{715DB4BA-F989-4DF6-B46F-5ED26A32B2DD} = {CCADA0BC-61CF-4B4B-96BA-A3B0C0A7F54D}
|
||||
{C2AD09BD-D579-45A7-ACA3-E4EF3BC027D2} = {CCADA0BC-61CF-4B4B-96BA-A3B0C0A7F54D}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {9F8F8A4D-7B8D-4C2A-AC5E-CD7117F74C03}
|
||||
EndGlobalSection
|
||||
|
||||
Reference in New Issue
Block a user