バリデーション有効の場合のみ押下できるボタンを実装する

XAML

<!-- 冒頭 -->
<Window x:Class="AddressBook.EditWindow"
        xmlns:cnv="clr-namespace:AddressBook.converter"
        xmlns:val="clr-namespace:AddressBook.validator"
    <Window.Resources>
        <cnv:BoolConverter x:Key="BoolConverter"/>
        <cnv:MultiBoolConverter x:Key="MultiBoolConverter"/>

<!-- 対象のコントロール -->
<TextBox x:Name="textZip" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="2" Margin="4,4,4,4">
    <TextBox.Text>
        <Binding Converter="{StaticResource ZipConverter}" Path="ZipCode" UpdateSourceTrigger="PropertyChanged">
            <Binding.ValidationRules>
                <val:ZipValidationRule ValidatesOnTargetUpdated="True"/>
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

<!-- 対象のコントロールがひとつの場合 -->
<Button x:Name="buttonZip" Content="検索" Margin="4,4,4,4" Grid.Column="3" Grid.Row="1" Click="buttonZip_Click">
    <Button.IsEnabled>
        <Binding Converter="{StaticResource BoolConverter}" ElementName="textZip" Path="(Validation.HasError)"/>
    </Button.IsEnabled>
</Button>

<!-- 対象のコントロールが複数の場合 -->
<Button x:Name="buttonCreate" Content="登録" Margin="4,4,4,4" Grid.Column="2" Grid.Row="10" Click="buttonCreate_Click">
    <Button.IsEnabled>
        <MultiBinding Converter="{StaticResource MultiBoolConverter}">
            <Binding ElementName="textName" Path="(Validation.HasError)"/>
            <Binding ElementName="textZip" Path="(Validation.HasError)"/>
            <Binding ElementName="comboPref" Path="(Validation.HasError)"/>
            <Binding ElementName="textCity" Path="(Validation.HasError)"/>
            <Binding ElementName="comboTown" Path="(Validation.HasError)"/>
            <Binding ElementName="textBlock" Path="(Validation.HasError)"/>
        </MultiBinding>
    </Button.IsEnabled>
</Button>

Converter

対象コントロールのValidation.HasErrorがfalseの場合、ボタンのIsEnabledがtrueになればよいのでvalueを反転させる。

using System;
using System.Globalization;
using System.Windows.Data;

namespace AddressBook.converter
{
    class BoolConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return !(bool)value;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

対象コントロールが複数の場合はIMultiValueConverterを実装する。object[] valuesにはXAMLで指定した対象コントロールのValidation.HasErrorが入っている。

using System;
using System.Globalization;
using System.Linq;
using System.Windows.Data;

namespace AddressBook.converter
{
    class MultiBoolConverter : 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();
        }
    }
}

トップページ

コメント

タイトルとURLをコピーしました