Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update reactive-view-model.md #473

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions docs/concepts/reactiveui/reactive-view-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,65 @@ Any change to the view model description property is achieved using the `set` ac
When _Avalonia UI_ uses the binding to **Update** the view model, the `set` accessor ensures that any parts of the view model that depend on the description property can also react to the change if necessary.

On the next page, you will learn how a reactive command acts as a special case of the view model update.

## Performing Data Validation
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this should have its own page under the ReactiveUI section, especially if this is a standalone example. Can be done in a future PR though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree on the separate page, will be worthwhile doing in the future with more examples and perhaps deeper dive on the workings. I am still learning and not an expert on MVVM, but this gave me a lot of confusion, if what I gave was documented, it would have saved me a ton of time.

ReactiveUI provides the ability to perform data validation from the ViewModel that integrates well with the Avalonia fluent controls. The example shows how this can be done. The example is for a ViewModel that exposes a directory path string that is bounded to a TextBox control on the View.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit imprecise to say it integrates with the Avalonia Fluent controls as it will work for any theme. It would integrate with one of Avalonia's data validation plugins: either Data Annotations, INotifyDataErrorInfo, or via exceptions. I'm not sure which one ReactiveUI is using here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took a peek at the ReactiveValidationObject and it implemented the ReactiveObject, IValidatableViewModel, INotifyDataErrorInfo, thats what make this a lot easier to implement and bypass the need for me to learn too much at this stage about INotifyDataErrorInfo


Steps to enable data validation on the ViewModel:
1. Download the ReactiveUI.Validation nuget package (for desktop applications)
2. Change the inheritance of the ViewModel to ReactiveValidationObject
3. Include a this.ValidationRule in the ViewModel constructor, which provides the validation check for the ViewModel property and corresponding validation error message.

The code below shows the MainWindowViewModel.cs and MainWindow.axaml
```C#
using System.IO;
using ReactiveUI;
using ReactiveUI.Validation.Extensions;
using ReactiveUI.Validation.Helpers;

namespace AvaloniaApplication3.ViewModels;

public class MainWindowViewModel : ReactiveValidationObject
{
private string _directoryPath = string.Empty;

public string DirectoryPath
{
get => _directoryPath;
set => this.RaiseAndSetIfChanged(ref _directoryPath, value);
}

public MainWindowViewModel()
{
DirectoryPath = "C:\\BogusPath\\";
this.ValidationRule(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do wish there was more than one validation. Ideally one that requires multiple properties, but examples are hard to write.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might write more examples as I use more of this and actually understands how it works..

vm => vm.DirectoryPath,
path => Directory.Exists(path),
"You must specify a valid directory path.");

}
}
```
```xaml
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:AvaloniaApplication3.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="AvaloniaApplication3.Views.MainWindow"
x:DataType="vm:MainWindowViewModel"
Width="800" Height="300" WindowStartupLocation="CenterScreen"
Icon="/Assets/avalonia-logo.ico"
Title="AvaloniaApplication3">

<TextBox
Name="DirectoryPathTextBox"
VerticalAlignment="Top"
Text="{Binding DirectoryPath}"/>

</Window>
```
Below is the output:

![Avalonia-ReactiveUI-DataValidation](https://github.com/AvaloniaUI/avalonia-docs/assets/130417839/75aede6b-f8cc-4bb8-8520-f9a8f24aa779)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The image should also be committed to the repository. ie. in /img/concepts/reactiveui.