I'm trying to learn ReactiveUI
. Currently I'm playing with ReactiveUI.Validation
.
I'm using a simple TextBox
. Everything is working as expected if the binding doesn't have UpdateSourceTrigger=PropertyChanged
. If i add it, it will hang when i type something in the textbox.
What do I miss?
Here is the MainWindow not working code:
<rxui:ReactiveWindow x:Class="ReactiveValidationTest.MainWindow"
x:TypeArguments="local:MainViewModel"
xmlns:rxui="http://reactiveui.net"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ReactiveValidationTest"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<StackPanel Margin="50">
<TextBox x:Name="TxtBox"
Text="{Binding InputText,UpdateSourceTrigger=PropertyChanged}"
HorizontalAlignment="Stretch"/>
<TextBox HorizontalAlignment="Stretch"/>
</StackPanel>
</rxui:ReactiveWindow>
The code behind:
using ReactiveUI;
using ReactiveUI.Validation.Extensions;
using System.Reactive.Disposables;
namespace ReactiveValidationTest
{
public partial class MainWindow : ReactiveWindow<MainViewModel>
{
public MainWindow()
{
InitializeComponent();
ViewModel = new MainViewModel();
this.WhenActivated(d =>
{
this.WhenAnyValue(x => x.ViewModel)
.BindTo(this, x => x.DataContext)
.DisposeWith(d);
this.BindValidation(ViewModel, vm => vm.InputText, v => v.TxtBox.Text);
});
}
}
}
And the ViewModel:
using ReactiveUI.Fody.Helpers;
using ReactiveUI.Validation.Extensions;
using ReactiveUI.Validation.Helpers;
namespace ReactiveValidationTest
{
public class MainViewModel : ReactiveValidationObject
{
[Reactive]
public string InputText { get; set; }
//ctor
public MainViewModel()
{
this.ValidationRule(vm => vm.InputText,
txt => !string.IsNullOrEmpty(txt),
"Can not be null or Empty");
}
}
}
Thanks.
You have infinite loop, because you use this code:
this.BindValidation(ViewModel, vm => vm.InputText, v => v.TxtBox.Text);
Your current code reads input form control and set property, then ValidationRule
is trying to update control, to show error message. It triggers update of input control, so again - it triggers ValidationRule
. You use this mechanism wrong.
BindValidation
method should be used to bind error message for given rule, which is connected with vm property to control which is designated to show that message.
You are trying to use build-in WPF mechanism which uses INotifyDataErrorInfo
and your code is almost good. You should remove this.BindingValidation
, because binding in XAML
already do the job related with error message.