WPFでint型をバインドしたTextBoxとかって入力エラーがあると赤色枠がついていい感じにしてくれますよね。ただしViewModelからは、そのエラーは検知できない。 でも、ボタンは押せないようにしたい。そんなときは、こんなXAMLで実現できます。
<Window x:Class="WpfApplication12.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:WpfApplication12" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <local:IsAllFalseConverter x:Key="IsAllFalseConverter" /> </Window.Resources> <Window.DataContext> <local:MainWindowViewModel /> </Window.DataContext> <StackPanel> <TextBox x:Name="TextBoxInput1" Text="{Binding Input1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> <TextBlock Text="{Binding (Validation.HasError), ElementName=TextBoxInput1}" /> <TextBox x:Name="TextBoxInput2" Text="{Binding Input2, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> <TextBlock Text="{Binding (Validation.HasError), ElementName=TextBoxInput2}" /> <Button Content="OK"> <Button.IsEnabled> <MultiBinding Converter="{StaticResource IsAllFalseConverter}"> <Binding ElementName="TextBoxInput1" Path="(Validation.HasError)" /> <Binding ElementName="TextBoxInput2" Path="(Validation.HasError)" /> </MultiBinding> </Button.IsEnabled> </Button> </StackPanel> </Window>
IsAllFalseConverterは以下のような感じで。
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Data; namespace WpfApplication12 { public class IsAllFalseConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { return values.OfType<bool>().All(x => !x); } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } }
これで、エラーのないときだけ押せるボタンの出来上がり。WPFのXAML強いですねやっぱり。
ここまで書いておいて
ViewModelにstringで受け取るようにしておいて、そこでエラーチェックとかコマンドの実行可否を判断するようにするのがおすすめです。はい。