C#のWPFで入力値検証をカスタマイズ

WPFでつくったTextBoxなどは、変数をバインドしておくと入力規制が働いてくれる。

 

たとえば、変数が数値型だった時、TextBoxに英字が入力されると赤枠表示になって不正な文字が入力されている事を知らせてくれる。

これはValidationRuleという仕組みが機能してくれるおかげ。

Binding.ValidatesOnExceptionsプロパティがtureであると、変数へ入力値を入れようとしてexceptionが発生すると、上記のように警告してくれる。

 

 

もっと凝った入力規制(マイナスはダメとか1~100までとか) をしたい場合は、自分でルールを作って使う事が出来る。


ルールを作る

ValidationRuleクラスを継承して新しいクラスを作り、

Validateメソッドをオーバーライドして独自ルールを書き込む。

 

以下は最大最小値、空文字の許可などをチェックできるルール。

using System;
using System.Globalization;
using System.Windows.Controls;

namespace xxxx
{
    public class NumberValidationRule : ValidationRule
    {
        public double MinValue { get; set; }
        public double MaxValue { get; set; }
        public bool NotEmpty { get; set; }
        public string MessageHeader { get; set; }

        public NumberValidationRule()
        {
            MinValue = double.MinValue;
            MaxValue = double.MaxValue;
            NotEmpty = false;
            MessageHeader = null;
        }

        public NumberValidationRule(double min, double max, bool notEmpty = false, string msgHeader = null)
        {
            MinValue = min;
            MaxValue = max;
            NotEmpty = notEmpty;
            MessageHeader = msgHeader;
        }

        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            if (null == value)
            {
                if (NotEmpty)
                {
                    var msg = "値を入力してください。";
                    if (!string.IsNullOrWhiteSpace(MessageHeader))
                        msg = MessageHeader + "に" + msg;
                    return new ValidationResult(false, msg);
                }
                else
                    return ValidationResult.ValidResult;
            }
            string str = value.ToString();
            if (string.IsNullOrEmpty(str))
            {
                if (NotEmpty)
                {
                    var msg = "値を入力してください。";
                    if (!string.IsNullOrWhiteSpace(MessageHeader))
                        msg = MessageHeader + "に" + msg;
                    return new ValidationResult(false, msg);
                }
                else
                    return ValidationResult.ValidResult;
            }

            double ret;
            if (!double.TryParse(str, out ret))
            {
                var msg = "数値を入力してください。";
                if (!string.IsNullOrWhiteSpace(MessageHeader))
                    msg = MessageHeader + "に" + msg;
                return new ValidationResult(false, msg);
            }
            if ((MinValue > ret) || (MaxValue < ret))
            {
                var msg = "値が範囲外です。(" + MinValue + "~" + MaxValue + ")";
                if (!string.IsNullOrWhiteSpace(MessageHeader))
                    msg = MessageHeader + "の" + msg;
                return new ValidationResult(false, msg);
            }

            return ValidationResult.ValidResult;
        }
    }
}

作ったルールをXAMLへ埋め込む

作ったクラスのnamespaseを参照出来るようにしつつ(06行目) 

TextBoxのBinding.ValidationRulesへ埋め込む。(13行目) 

合わせてプロパティをセットする事で、下記では1から100以外の数値をエラーにしている。 

<Window x:Class="ForestGIS.Config.AccountSettingWindow"
        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:localxxxx="clr-namespace:xxxx"
        mc:Ignorable="d">
    <StackPanel Margin="10">
        <TextBox Grid.Column="2" Grid.Row="0" Margin="0,5">
            <TextBox.Text>
                <Binding Path="Name">
                    <Binding.ValidationRules>
                        <localxxxx:NumberValidationRule MinValue="1" MaxValue="100"/>
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>
    </StackPanel>
</Window>

 

 

コメントをお書きください

コメント: 1
  • #1

    タツヤ (土曜日, 02 3月 2019 22:36)

    WPFてなんだ?