ソースコード
<Window x:Class="ValidationSample.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:i="clr-namespace:Microsoft.Xaml.Behaviors;assembly=Microsoft.Xaml.Behaviors"
xmlns:interactivity="clr-namespace:Reactive.Bindings.Interactivity;assembly=ReactiveProperty.WPF"
xmlns:local="clr-namespace:ValidationSample"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Grid>
<StackPanel>
<WrapPanel>
<Label Content="数値" />
<Label Content="{Binding ErrorText1.Value}" Foreground="Red" HorizontalAlignment="Right" />
</WrapPanel>
<TextBox Text="{Binding Text1.Value, UpdateSourceTrigger=PropertyChanged}" />
<Button Content="実行" Command="{Binding ExecCommand}" />
</StackPanel>
</Grid>
</Window>
ファイル名:MainWindowViewModel.cs
using System;
using System.ComponentModel;
using Reactive.Bindings;
using Reactive.Bindings.Extensions;
using System.Reactive.Disposables;
using System.Diagnostics;
using System.Windows.Threading;
using System.Windows;
namespace ValidationSample;
public class MainWindowViewModel : INotifyPropertyChanged, IDisposable
{
public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged(string name)
{
if (PropertyChanged == null) return;
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
private CompositeDisposable Disposable { get; } = new ();
public void Dispose() => Disposable.Dispose();
public ReactiveProperty<string> Text1 { get; }
public ReactiveProperty<string> ErrorText1 { get; }
public ReactiveCommand ExecCommand { get; }
public MainWindowViewModel()
{
Text1 = new ReactiveProperty<string>()
.SetValidateNotifyError(
x =>
{
int value = 0;
if (string.IsNullOrEmpty(x)) return "必須";
if (int.TryParse(x, out value) == false) return "数値";
if (value <= 0) return "0より大きい数値";
if ((value % 2) == 0) return "奇数";
return null;
})
.AddTo(Disposable);
ErrorText1 = new ReactiveProperty<string>()
.AddTo(Disposable);
Text1.ObserveValidationErrorMessage()
.Subscribe(x => ErrorText1.Value = x ?? "");
ExecCommand =
new[]
{
Text1.ObserveHasErrors,
}
.CombineLatestValuesAreAllFalse()
.ToReactiveCommand();
ExecCommand.WithSubscribe(_ =>
{
MessageBox.Show(Text1.Value);
});
}
}
実行例
初期状態
数値以外を入力
0以下の数値を入力
奇数を入力すると入力値のチェックが通り「実行」ボタンが活性化し押せるようになります。
コメント