【发布时间】:2019-12-13 10:26:40
【问题描述】:
我们在 .Net Core WPF 应用程序中使用 ReactiveUI.WPF 11.0.1。我们正在考虑用基于 ReactiveUI 的绑定替换所有基于 XAML 的绑定。 实现 INotifyPropertyChanged 和 INotifyDataErrorInfo 的域类型有一个 ViewModel:
public class ItemViewModel : INotifyPropertyChanged, INotifyDataErrorInfo
{
private string Error => string.IsNullOrEmpty(Name) ? "Empty name" : string.Empty;
private string _name;
public string Name
{
get => _name;
set
{
_name = value;
OnPropertyChanged();
}
}
public IEnumerable GetErrors(string propertyName)
{
if (string.IsNullOrEmpty(Error))
return Enumerable.Empty<string>();
return new[] {Error};
}
public bool HasErrors => !string.IsNullOrEmpty(Error);
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
}
}
窗口有一个ViewModel:
public class MainWindowViewModel: ReactiveObject
{
public ItemViewModel ItemA { get; } = new ItemViewModel();
public ItemViewModel ItemB { get; } = new ItemViewModel();
}
还有一个主窗口:
<reactiveUi:ReactiveWindow
x:TypeArguments="local:MainWindowViewModel"
x:Class="WpfApp1.MainWindow"
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:WpfApp1"
xmlns:reactiveUi="http://reactiveui.net"
mc:Ignorable="d">
<StackPanel>
<TextBox Text="{Binding ItemA.Name}" />
<TextBox x:Name="ItemBTextBox" />
</StackPanel>
</reactiveUi:ReactiveWindow>
public partial class MainWindow : ReactiveWindow<MainWindowViewModel>
{
public MainWindow()
{
InitializeComponent();
ViewModel = new MainWindowViewModel();
DataContext = ViewModel;
this.WhenActivated(disposables =>
{
this.Bind(ViewModel, x => x.ItemB.Name, x => x.ItemBTextBox.Text);
});
}
}
当第一个 TextBox 的 Text 属性为空时,它会显示默认的 WPF ErrorTemplate(红色边框)。但是,第二个(使用基于 ReactiveUI 的绑定)没有。有没有办法使用 ReactiveUI 的绑定与 WPF 的 ErrorTemplates 自动工作而不更改 ItemViewModel 类?
【问题讨论】:
-
您阅读过响应式用户界面文档吗?如果是这样,也许您应该解释为什么您不遵循示例并像他们那样实施? reactiveui.net/docs/handbook/user-input-validation
-
@Andy,我读过。我们使用 FluentValidation,因此所有验证逻辑都在单独的 AbstractValidators 中定义(每个域接口一个验证器)。这些验证器用于实现域接口的不可变类(构造函数中的validator.ValidateAndThrow(this))和ViewModels(将INotifyDataErrorInfo 的实现委托给_validationTemplate)。文档中的示例继承了 ReactiveValidationObject
,验证逻辑定义在同一个类中。我们希望将视图模型及其验证逻辑分开 -
@Andy 该文档还指出 FluentValidation 是一个很棒的工具,但没有提供任何将其集成到 ReactiveUI 验证中的示例。我已经看到一些集成这两个的 NuGet 包,我将研究它们。
-
FWIW Fluentvalidation 似乎是人们最喜欢或最讨厌的东西。
-
您使用 FromEventPattern 将事件包装到 Observable 中以将其转换为反应式 UI 属性可能吗?这是一篇关于这个想法的快速文章Wrapping Events
标签: wpf validation fluentvalidation reactiveui