ReactiveUI.Validation 不适用于 TextBox 如果绑定具有 UpdateSourceTrigger=PropertyChanged(WPF、.net 5.0)

ReactiveUI.Validation is not working on TextBox If binding has UpdateSourceTrigger=PropertyChanged (WPF, .net 5.0)

我正在努力学习 ReactiveUI。目前我正在玩 ReactiveUI.Validation.

我使用的是简单的 TextBox。如果绑定没有 UpdateSourceTrigger=PropertyChanged,一切都按预期工作。如果我添加它,当我在文本框中键入内容时它会挂起。 我想念什么?

这是 MainWindow 不工作的代码:

<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>

后面的代码:

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);
            });
        }
    }
}

和视图模型:

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");
        }
    }
}

谢谢。

你有无限循环,因为你使用了这段代码:

this.BindValidation(ViewModel, vm => vm.InputText, v => v.TxtBox.Text);

您当前的代码读取输入表单控件并设置 属性,然后 ValidationRule 正在尝试更新控件,以显示错误消息。它会触发输入控件的更新,所以再次 - 它会触发 ValidationRule。你用错了这个机制。

BindValidation 方法应该用于绑定给定规则的错误消息,它与 vm 属性 连接以控制指定哪个显示该消息。

您正在尝试使用使用 INotifyDataErrorInfo 的内置 WPF 机制,并且您的代码几乎是好的。您应该删除 this.BindingValidation,因为 XAML 中的绑定已经执行了与错误消息相关的工作。