LoginViewModel.cs 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. using System;
  2. using System.Reactive;
  3. using System.Reactive.Linq;
  4. using System.Runtime.Serialization;
  5. using System.Threading.Tasks;
  6. using ReactiveUI;
  7. using ReactiveUI.Fody.Helpers;
  8. namespace ReactiveExample;
  9. //
  10. // This view model can be easily shared across different UI frameworks.
  11. // For example, if you have a WPF or XF app with view models written
  12. // this way, you can easily port your app to Terminal.Gui by implementing
  13. // the views with Terminal.Gui classes and ReactiveUI bindings.
  14. //
  15. // We mark the view model with the [DataContract] attributes and this
  16. // allows you to save the view model class to the disk, and then to read
  17. // the view model from the disk, making your app state persistent.
  18. // See also: https://www.reactiveui.net../docs/handbook/data-persistence/
  19. //
  20. [DataContract]
  21. public class LoginViewModel : ReactiveObject
  22. {
  23. private readonly ObservableAsPropertyHelper<bool> _isValid;
  24. private readonly ObservableAsPropertyHelper<int> _passwordLength;
  25. private readonly ObservableAsPropertyHelper<int> _usernameLength;
  26. public LoginViewModel ()
  27. {
  28. IObservable<bool> canLogin = this.WhenAnyValue (
  29. x => x.Username,
  30. x => x.Password,
  31. (username, password) =>
  32. !string.IsNullOrEmpty (username) && !string.IsNullOrEmpty (password)
  33. );
  34. _isValid = canLogin.ToProperty (this, x => x.IsValid);
  35. Login = ReactiveCommand.CreateFromTask<EventArgs> (
  36. e => Task.Delay (TimeSpan.FromSeconds (1)),
  37. canLogin
  38. );
  39. _usernameLength = this
  40. .WhenAnyValue (x => x.Username)
  41. .Select (name => name.Length)
  42. .ToProperty (this, x => x.UsernameLength);
  43. _passwordLength = this
  44. .WhenAnyValue (x => x.Password)
  45. .Select (password => password.Length)
  46. .ToProperty (this, x => x.PasswordLength);
  47. Clear = ReactiveCommand.Create<EventArgs> (e => { });
  48. Clear.Subscribe (
  49. unit =>
  50. {
  51. Username = string.Empty;
  52. Password = string.Empty;
  53. }
  54. );
  55. }
  56. [IgnoreDataMember]
  57. public ReactiveCommand<EventArgs, Unit> Clear { get; }
  58. [IgnoreDataMember]
  59. public bool IsValid => _isValid.Value;
  60. [IgnoreDataMember]
  61. public ReactiveCommand<EventArgs, Unit> Login { get; }
  62. [Reactive]
  63. [DataMember]
  64. public string Password { get; set; } = string.Empty;
  65. [IgnoreDataMember]
  66. public int PasswordLength => _passwordLength.Value;
  67. [Reactive]
  68. [DataMember]
  69. public string Username { get; set; } = string.Empty;
  70. [IgnoreDataMember]
  71. public int UsernameLength => _usernameLength.Value;
  72. }