LoginViewModel.cs 3.2 KB

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