|
@@ -2,21 +2,15 @@
|
|
|
|
|
|
This small demo gives an example of using the `CommunityToolkit.MVVM` framework's `ObservableObject`, `ObservableProperty`, and `IRecipient<T>` in conjunction with `Microsoft.Extensions.DependencyInjection`.
|
|
This small demo gives an example of using the `CommunityToolkit.MVVM` framework's `ObservableObject`, `ObservableProperty`, and `IRecipient<T>` in conjunction with `Microsoft.Extensions.DependencyInjection`.
|
|
|
|
|
|
-### Startup
|
|
|
|
-
|
|
|
|
Right away we use IoC to load our views and view models.
|
|
Right away we use IoC to load our views and view models.
|
|
|
|
|
|
``` csharp
|
|
``` csharp
|
|
// As a public property for access further in the application if needed.
|
|
// As a public property for access further in the application if needed.
|
|
public static IServiceProvider Services { get; private set; }
|
|
public static IServiceProvider Services { get; private set; }
|
|
-
|
|
|
|
-. . .
|
|
|
|
-
|
|
|
|
|
|
+...
|
|
// In Main
|
|
// In Main
|
|
Services = ConfigureServices ();
|
|
Services = ConfigureServices ();
|
|
-
|
|
|
|
-. . .
|
|
|
|
-
|
|
|
|
|
|
+...
|
|
private static IServiceProvider ConfigureServices ()
|
|
private static IServiceProvider ConfigureServices ()
|
|
{
|
|
{
|
|
var services = new ServiceCollection ();
|
|
var services = new ServiceCollection ();
|
|
@@ -41,13 +35,9 @@ internal partial class LoginView : IRecipient<Message<LoginAction>>
|
|
{
|
|
{
|
|
// Initialize our Receive method
|
|
// Initialize our Receive method
|
|
WeakReferenceMessenger.Default.Register (this);
|
|
WeakReferenceMessenger.Default.Register (this);
|
|
-
|
|
|
|
...
|
|
...
|
|
-
|
|
|
|
ViewModel = viewModel;
|
|
ViewModel = viewModel;
|
|
-
|
|
|
|
...
|
|
...
|
|
-
|
|
|
|
passwordInput.TextChanged += (_, _) =>
|
|
passwordInput.TextChanged += (_, _) =>
|
|
{
|
|
{
|
|
ViewModel.Password = passwordInput.Text;
|
|
ViewModel.Password = passwordInput.Text;
|
|
@@ -58,40 +48,30 @@ internal partial class LoginView : IRecipient<Message<LoginAction>>
|
|
if (!ViewModel.CanLogin) { return; }
|
|
if (!ViewModel.CanLogin) { return; }
|
|
ViewModel.LoginCommand.Execute (null);
|
|
ViewModel.LoginCommand.Execute (null);
|
|
};
|
|
};
|
|
-
|
|
|
|
...
|
|
...
|
|
-
|
|
|
|
|
|
+ // Let the view model know the view is intialized.
|
|
Initialized += (_, _) => { ViewModel.Initialized (); };
|
|
Initialized += (_, _) => { ViewModel.Initialized (); };
|
|
}
|
|
}
|
|
-
|
|
|
|
...
|
|
...
|
|
-
|
|
|
|
}
|
|
}
|
|
```
|
|
```
|
|
|
|
|
|
-Momentarily slipping over to the view model, all bindable properties use some form of `ObservableProperty` with the class deriving from `ObservableObject`. Commands are of the `RelayCommand` type.
|
|
|
|
|
|
+Momentarily slipping over to the view model, all bindable properties use some form of `ObservableProperty` with the class deriving from `ObservableObject`. Commands are of the `RelayCommand` type. The use of `ObservableProperty` generates the code for handling `INotifyPropertyChanged` and `INotifyPropertyChanging`.
|
|
|
|
|
|
``` csharp
|
|
``` csharp
|
|
-
|
|
|
|
internal partial class LoginViewModel : ObservableObject
|
|
internal partial class LoginViewModel : ObservableObject
|
|
{
|
|
{
|
|
...
|
|
...
|
|
-
|
|
|
|
[ObservableProperty]
|
|
[ObservableProperty]
|
|
private bool _canLogin;
|
|
private bool _canLogin;
|
|
|
|
|
|
private string _password;
|
|
private string _password;
|
|
-
|
|
|
|
...
|
|
...
|
|
-
|
|
|
|
public LoginViewModel ()
|
|
public LoginViewModel ()
|
|
{
|
|
{
|
|
...
|
|
...
|
|
-
|
|
|
|
Password = string.Empty;
|
|
Password = string.Empty;
|
|
-
|
|
|
|
- ...
|
|
|
|
-
|
|
|
|
|
|
+ ...
|
|
LoginCommand = new (Execute);
|
|
LoginCommand = new (Execute);
|
|
|
|
|
|
Clear ();
|
|
Clear ();
|
|
@@ -100,9 +80,7 @@ internal partial class LoginViewModel : ObservableObject
|
|
|
|
|
|
async void Execute () { await Login (); }
|
|
async void Execute () { await Login (); }
|
|
}
|
|
}
|
|
-
|
|
|
|
...
|
|
...
|
|
-
|
|
|
|
public RelayCommand LoginCommand { get; }
|
|
public RelayCommand LoginCommand { get; }
|
|
|
|
|
|
public string Password
|
|
public string Password
|
|
@@ -121,7 +99,6 @@ The use of `WeakReferenceMessenger` provides one method of signaling the view fr
|
|
|
|
|
|
``` csharp
|
|
``` csharp
|
|
...
|
|
...
|
|
-
|
|
|
|
private async Task Login ()
|
|
private async Task Login ()
|
|
{
|
|
{
|
|
SendMessage (LoginAction.LoginProgress, LOGGING_IN_PROGRESS_MESSAGE);
|
|
SendMessage (LoginAction.LoginProgress, LOGGING_IN_PROGRESS_MESSAGE);
|
|
@@ -149,7 +126,6 @@ private void ValidateLogin ()
|
|
CanLogin = !string.IsNullOrEmpty (Username) && !string.IsNullOrEmpty (Password);
|
|
CanLogin = !string.IsNullOrEmpty (Username) && !string.IsNullOrEmpty (Password);
|
|
SendMessage (LoginAction.Validation);
|
|
SendMessage (LoginAction.Validation);
|
|
}
|
|
}
|
|
-
|
|
|
|
...
|
|
...
|
|
```
|
|
```
|
|
|
|
|
|
@@ -176,5 +152,3 @@ public void Receive (Message<LoginAction> message)
|
|
Application.Refresh ();
|
|
Application.Refresh ();
|
|
}
|
|
}
|
|
```
|
|
```
|
|
-
|
|
|
|
-There are other ways of handling cross-thread communication, this gives just one example.
|
|
|