質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

2回答

5131閲覧

ReactivePropertyでTextBoxが空欄時にButtonをDisableにしたい。

mathter

総合スコア1

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2020/10/01 12:14

前提・実現したいこと

ReactivePropertyでValidationを行い、値が特定の範囲内でなければ、ボタンを押せなくしたいです。
概ね期待通りの動作は実現できたのですが、TextBoxが空欄の場合にエラー状態となるにも関わらず、ボタンが押せてしまいます。
空欄状態でもボタンをDisableにするにはどうすれば良いでしょうか?

該当のソースコード

C#

1// ViewModel 2using Reactive.Bindings; 3using System; 4using System.Collections.Generic; 5using System.ComponentModel.DataAnnotations; 6using System.Reactive.Linq; 7using System.Security.Cryptography.X509Certificates; 8using System.Text; 9 10namespace ValidationApp 11{ 12 class MainWindowsViewModel 13 { 14 public MainWindowsViewModel() 15 { 16 this.InitializeProperty(); 17 } 18 19 [Required] 20 [Range(0,100)] 21 public ReactiveProperty<double> ValidateParameter { get; private set; } 22 23 public ReactiveCommand ValidCommand { get; private set; } 24 25 private void InitializeProperty() { 26 this.ValidateParameter = new ReactiveProperty<double>().SetValidateAttribute(() => this.ValidateParameter); 27 this.ValidCommand = this.ValidateParameter.ObserveHasErrors.Select(x => !x).ToReactiveCommand(); 28 } 29 } 30} 31

C#

1<!--View--> 2<Window x:Class="ValidationApp.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 6 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 7 xmlns:local="clr-namespace:ValidationApp" 8 mc:Ignorable="d" 9 Title="MainWindow" Height="450" Width="800"> 10 <StackPanel> 11 <TextBox Text="{Binding ValidateParameter.Value, UpdateSourceTrigger=PropertyChanged}" Width="100" Margin="10" /> 12 <Button Content="Valid" Command="{Binding ValidCommand}" Width="100"/> 13 14 </StackPanel> 15</Window> 16

補足情報(FW/ツールのバージョンなど)

ReactiveProperty: 7.4.1
.NET Core 3.1

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ReactiveProperty<double>ReactiveProperty<string>で実装して、
doubleに変換可能か判定する自作Validationクラスを用意してみてはいかがでしょうか?

以前ざっとですがバリデーションやボタンの活性/非活性の挙動についてまとめていたので、参考にどうぞ。
ReactivePropertyを使ってバリデーションエラーを表示する

投稿2020/10/01 13:28

takapi_cs

総合スコア349

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mathter

2020/10/07 22:39

やはりViewModelで一旦ReactiveProperty<string>で受けるのがスタンダードな方法なんですかね?
takapi_cs

2020/10/09 11:40

個人的にはstringだと自由度が高くて手っ取り早く実装できるので良いかなと思いました。 そもそもTN8001さんの方法をとった経験があまりなかったのもありますが…
guest

0

ベストアンサー

結構悩ましいですね(doubleなとこも地味にいじわる^^;
takapi_csさんの回答が真っ当という気がしますが、手抜きならこんなのもあるかなと。

コンバータは適当です^^; お好きな実装をどうぞ。
KeepTextBoxDisplaySynchronizedWithTextPropertyの影響範囲はよくわかりません(使ったことないので^^;

xml

1<Window 2 x:Class="Questions295331.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:local="clr-namespace:Questions295331" 6 Width="800" 7 Height="450"> 8 <StackPanel> 9 <TextBox 10 x:Name="textBox" 11 Width="100" 12 Margin="10" 13 Text="{Binding ValidateParameter.Value, UpdateSourceTrigger=PropertyChanged}" /> 14 <Button 15 Width="100" 16 Command="{Binding ValidCommand}" 17 Content="Valid" 18 IsEnabled="{Binding (Validation.HasError), Converter={local:InverseBooleanConverter}, ElementName=textBox}" /> 19 </StackPanel> 20</Window>

cs

1using System; 2using System.ComponentModel.DataAnnotations; 3using System.Diagnostics; 4using System.Globalization; 5using System.Windows; 6using System.Windows.Data; 7using System.Windows.Markup; 8using Reactive.Bindings; 9 10namespace Questions295331 11{ 12 public class InverseBooleanConverter : MarkupExtension, IValueConverter 13 { 14 public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 15 => !(bool)value; 16 public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 17 => throw new NotImplementedException(); 18 public override object ProvideValue(IServiceProvider serviceProvider) => this; 19 } 20 21 class MainWindowsViewModel 22 { 23 [Range(0, 100d)] 24 public ReactiveProperty<double> ValidateParameter { get; } 25 26 public ReactiveCommand ValidCommand { get; } 27 28 public MainWindowsViewModel() 29 { 30 ValidateParameter = new ReactiveProperty<double>() 31 .SetValidateAttribute(() => ValidateParameter); 32 33 ValidCommand = new ReactiveCommand() 34 .WithSubscribe(() => Debug.WriteLine(ValidateParameter.Value)); 35 } 36 } 37 38 public partial class MainWindow : Window 39 { 40 public MainWindow() 41 { 42 FrameworkCompatibilityPreferences.KeepTextBoxDisplaySynchronizedWithTextProperty = false; 43 44 InitializeComponent(); 45 DataContext = new MainWindowsViewModel(); 46 } 47 } 48}

投稿2020/10/01 16:17

編集2023/07/23 07:24
TN8001

総合スコア9321

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問