2017年3月7日火曜日

DataGrid 入力チェック方法

WPFでDataGridを使って入力を行う際の チェック方法について、いろんなサイトで解説されているが、我流のTIPS。

やりたいこと
  1. 入力時に、単項目チェックを行う。今回は正の整数のみOKとする
  2. エラーの場合 背景色を指定の色にする。今回はピンクにする
  3. エラー内容を Tooltipに表示する
これを WPFの流儀にしたがってdatabindingで行う。



  1. DataGridに表示するDataListクラスを作成する。
    class DataList : ObservableCollection<clsData>
    {
    ---- 中略 ----
    }
    ポイント clsDataのコレクションであることをことを指定する。

  2. DataListを構成する clsDataクラスを作成する。
    public class clsData : IDataErrorInfo, INotifyPropertyChanged
        {
            ---- 中略 ----
            private string _Mmin;
            public string Mmin
            {
                get
                {
                    return _Mmin;
                }
                set
                {
                    _Mmin = value;
                    NotifyPropertyChanged("Mmin");
                }
            }
    
            ---- 中略 ----
    
            // -------------------------------------------------------------------------------------------------------------------
    
            // 今回は使わないが、IDataErrorInfo インターフェースでは実装しなければならない
            public string Error { get { return null; } }
    
            // これも実装必須のプロパティで、各プロパティに対応するエラーメッセージを返す
            public string this[string propertyName]
            {
                get
                {
                    string vv = null;
                    switch (propertyName)
                    {
                        case "Mmin": vv = this.Mmin; break;
                        case "Mmax": vv = this.Mmax; break;
                        case "Emin": vv = this.Emin; break;
                        case "Emax": vv = this.Emax; break;
                        default: return null;
                    }
    
                    if (String.IsNullOrEmpty(vv)) return null;
                    int a;
                    if (!int.TryParse(vv.ToString(), out a)) return "整数を入力してください";
                    if (a < 0) return "マイナスの入力はできません。";
                    return null;
                }
            }
    
            // -------------------------------------------------------------------------------------------------------------------
            public event PropertyChangedEventHandler PropertyChanged;
            private void NotifyPropertyChanged(String info)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(info));
                }
            }
        }
    ポイント
    ・インターフェース IDataErrorInfo および INotifyPropertyChangedを実装する。
    ・public string this[string propertyName] で プロパティ(項目)ごとのチェック方法・エラーメッセージを指定する。正常時 nullを返す。
    数値項目でもstringプロパティを定義、独自に数値チェックを行う。これにより、非数値を入力した際 いかにもユーザー受けしないシステム標準のエラーメッセージ「入力文字列の形式が正しくありません」を任意のメッセージに変更できる。

  3. XAML
    DataGlidに関する主要部分のみ下に示す。

    <DataGrid x:name="datagrid">
    <--- 中略 --->
    <DataGrid.Resources>
    <Style x:Key="TextBlockRightStyle" TargetType="{x:Type TextBlock}" BasedOn="{x:Static DataGridTextColumn.DefaultElementStyle}">
          <Setter Property="HorizontalAlignment" Value="Stretch" />
          <Setter Property="TextAlignment" Value="Right" />
          <Setter Property="Margin" Value="0,0,0,0" />
          <Setter Property="Padding" Value="0,2,6,0" />
          <Style.Triggers>
             <Trigger Property="Validation.HasError" Value="True">
                <Setter Property="Background" Value="Pink"/>
                <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
            </Trigger>
          </Style.Triggers>
    </Style>
    
    <Style x:Key="TextBoxRightStyle" TargetType="{x:Type TextBox}" BasedOn="{x:Static DataGridTextColumn.DefaultEditingElementStyle}">
          <Setter Property="HorizontalContentAlignment" Value="Right" />
          <Setter Property="Margin" Value="0,0,0,0" />
          <Setter Property="Padding" Value="0,2,4,0" />
          <Style.Triggers>
             <Trigger Property="Validation.HasError" Value="True">
                <Setter Property="Background" Value="Pink"/>
                <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
             </Trigger>
          </Style.Triggers>
    </Style>
    </DataGrid.Resources>
    
    <DataGrid.Columns>
        <DataGridTextColumn x:Name="Column1" Header="最低" Width="60" Binding="{Binding Mmin, ValidatesOnExceptions=True, NotifyOnValidationError=True, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged }" ElementStyle="{StaticResource TextBlockRightStyle}" EditingElementStyle="{StaticResource TextBoxRightStyle}" />
                        ---- 中略 ----
    </DataGrid.Columns>
    </DataGrid>
    ポイント
    ・エラー時の背景色・Tooltipは入力用スタイルおよび表示用スタイル双方に定義する
    ・表示用スタイル
    マージンをすべて0にする。こうしないとエラー項目を示す赤枠とグリッド罫線が重ならない。
    文字の右寄せを指定する際 右側に適当な隙間を空かせるにはpaddingで指定する。
    ・入力用スタイル
    文字の右寄せを指定する際 右側に適当な隙間を空かせるにはpaddingで指定する。
    ・padding値
    入力用スタイルと表示用スタイルで若干変えないと、Focus取得時・喪失時に文字が動く。

0 件のコメント:

コメントを投稿