1

IDataErrorInfo を使用して検証するデータグリッドがあります。保存ボタンをクリックしたときに検証が失敗した場合にエラーメッセージを表示したいと思います。私の問題は、検証エラーを取得する方法です。これらにうんざりしている人は解決策を知っていますか?私のデータグリッドは次のとおりです。

 <my:DataGrid Name="dgDamagedProducts" ItemsSource="{Binding}"   SelectionUnit="Cell"  BeginningEdit="dgDamagedProducts_BeginningEdit"  AutoGenerateColumns="False" Margin="13,75,9,117" RowEditEnding="dgDamagedProducts_RowEditEnding" GotFocus="dgDamagedProducts_GotFocus">
                    <my:DataGrid.Columns>
                        <!--0-ProductTransaction ID Column-->
                        <my:DataGridTextColumn  Header="ProductTransaction ID"  Visibility="Hidden" Width="0" Binding="{Binding ProductTransactionID}"></my:DataGridTextColumn>
                        <!--1-Item incID Column-->
                        <my:DataGridTextColumn  Header="ItemID" Visibility="Hidden" Width="0" Binding="{Binding ItemID}"></my:DataGridTextColumn>
                        <!--2-Product Code Column-->
                        <my:DataGridTextColumn  Header="Code" Width="100" Binding="{Binding ProductCode}"></my:DataGridTextColumn>
                        <!--3-Product Column-->
                        <my:DataGridTemplateColumn Header="Product Name" Width="200">
                            <my:DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <TextBlock Padding="3" Text="{Binding ProductName,NotifyOnValidationError=True,ValidatesOnDataErrors=True}" Style="{StaticResource TextBlockInError}"></TextBlock>
                                </DataTemplate>
                            </my:DataGridTemplateColumn.CellTemplate>
                            <my:DataGridTemplateColumn.CellEditingTemplate>
                                <DataTemplate>
                                    <TextBox x:Name="txtbxProduct" Style="{StaticResource TextBoxInError}" Text="{Binding Path=ProductName,Mode=TwoWay,NotifyOnValidationError=True,ValidatesOnDataErrors=True}" lc:FocusAttacher.Focus="True" TextChanged="txtbxProduct_TextChanged" PreviewKeyDown="txtbxProduct_PreviewKeyDown" ></TextBox>
                                </DataTemplate>
                            </my:DataGridTemplateColumn.CellEditingTemplate>
                        </my:DataGridTemplateColumn>

                        <!--7-Purchase Rate Column-->
                        <my:DataGridTextColumn Header="Purchase Rate" Width="100" Binding="{Binding PurchaseRate}" IsReadOnly="True"></my:DataGridTextColumn>
                        <!--8-Stock  Column-->
                        <my:DataGridTextColumn Header="Stock"  Binding="{Binding AvailableQty}" IsReadOnly="True" Visibility="Hidden"></my:DataGridTextColumn>
                        <!--9-Qty Column-->
                        <my:DataGridTemplateColumn Header="Qty" Width="100">
                            <my:DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding Qty,ValidatesOnDataErrors=True}" Style="{StaticResource TextBlockInError}"></TextBlock>
                                </DataTemplate>
                            </my:DataGridTemplateColumn.CellTemplate>
                            <my:DataGridTemplateColumn.CellEditingTemplate>
                                <DataTemplate>
                                    <RH:IntTextBox  x:Name="txtbxQty" Style="{StaticResource TextBoxInError}" Text="{Binding Qty,Mode=TwoWay,UpdateSourceTrigger=LostFocus,ValidatesOnDataErrors=True}" lc:FocusAttacher.Focus="True" LostFocus="txtbxQty_LostFocus" PreviewKeyDown="txtbxQty_PreviewKeyDown"></RH:IntTextBox>
                                </DataTemplate>
                            </my:DataGridTemplateColumn.CellEditingTemplate>
                        </my:DataGridTemplateColumn>
                        <!--10-Amount Column-->
                        <my:DataGridTextColumn Header="Amount" Width="100" Binding="{Binding Amount}" IsReadOnly="True" ></my:DataGridTextColumn>

                    </my:DataGrid.Columns>
                </my:DataGrid>

編集

私のクラスは次のとおりです。

 class clsDamagedProducts : INotifyPropertyChanged,IDataErrorInfo
{
    private int _ProductTransactionID;
    private int _ItemID;
    private string _ProductCode;
    private string _ProductName;
    private string _Batch;
    private int _UnitID;
    private string _UnitName;
    private decimal _PurchaseRate;
    private int _AvailableQty;
    private int _Qty;
    private decimal _Amount;
    private string _Remark;

    #region Property Getters and Setters

    public int ProductTransactionID 
    {
        get { return _ProductTransactionID; }
        set
        {
            _ProductTransactionID = value;
            OnPropertyChanged("ProductTransactionID");
        } 
    }

    public int ItemID
    {
        get { return _ItemID; }
        set
        {
            _ItemID = value;
            OnPropertyChanged("ItemID");
        }
    }

    public string ProductCode
    {
        get { return _ProductCode; }
        set
        {
            _ProductCode = value;
            OnPropertyChanged("ProductCode");
        }
    }

    public string ProductName
    {
        get { return _ProductName; }
        set
        {
            _ProductName = value;
            OnPropertyChanged("ProductName");
        }
    }

    public string Batch
    {
        get { return _Batch; }
        set
        {
            _Batch = value;
            OnPropertyChanged("Batch");
        }
    }

    public int UnitID
    {
        get { return _UnitID; }
        set
        {
            _UnitID = value;
            OnPropertyChanged("UnitID");
        }
    }

    public string UnitName
    {
        get { return _UnitName; }
        set
        {
            _UnitName = value;
            OnPropertyChanged("UnitName");
        }
    }

    public decimal PurchaseRate
    {
        get { return _PurchaseRate; }
        set
        {
            _PurchaseRate = value;
            OnPropertyChanged("PurchaseRate");
        }
    }

    public int AvailableQty
    {
        get { return _AvailableQty; }
        set
        {
            _AvailableQty = value;
            OnPropertyChanged("AvailableQty");
        }
    }

    public int Qty
    {
        get { return _Qty; }
        set
        {
            _Qty = value;
            this._Amount = this._Qty * this._PurchaseRate;
            OnPropertyChanged("Qty");
            OnPropertyChanged("Amount");
        }
    }

    public decimal Amount
    {
        get { return _Amount; }
        set
        {
            _Amount = value;
            OnPropertyChanged("Amount");
        }
    }

    public string Remark
    {
        get { return _Remark; }
        set
        {
            _Remark = value;
            OnPropertyChanged("Remark");
        }
    }

    #endregion

    #region IDataErrorInfo Members

    public string Error
    {
        get
        {
            return "";
        }
    }

    public string this[string name]
    {
        get
        {
            string result = null;

            if (name == "ProductName")
            {
                int count = Global.ItemExist(this._ProductName);
                if (count == 0) 
                {
                    result = "Invalid Product";

                }
            }

            else if (name == "Qty")
            {
                if (this._Qty >this._AvailableQty)
                {
                    result = "Qty must be less than Available Qty . Avaialble Qty : "+this._AvailableQty;
                }
            }

            return result;
        }
    }

    #endregion

    #region INotifyPropertyChanged Members

    // Declare the event
    public event PropertyChangedEventHandler PropertyChanged;

    //// Create the OnPropertyChanged method to raise the event
    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }

    #endregion
}
4

1 に答える 1

0

インターフェイスは、 という名前のIDataErrorInfoプロパティを公開しますError。これは、インターフェイスの一部として実装する必要があるインデクサーで設定したテキスト エラー メッセージを含むプロパティです。

ユーザーがカスタマイズしないと、このインターフェイスには一度に 1 つのエラー メッセージしか表示されないことに注意してください。このインターフェイスを実装するクラスの詳細を教えてくれなかったため、正確な例を示すことは困難です。ただし、次のようになります。

あなたのインデクサー:

public override string this[string propertyName]
{
    if (propertyName = "Name" && Name == string.Empty) return "Please add the name";
    return string.Empty;
}

インターフェイスがプロパティの変更を検出すると、このインデクサーを呼び出します。プロパティの名前がエラー メッセージとともにここにある場合、そのメッセージはインターフェイスを実装するデータ クラスErrorのプロパティに設定されます。したがって、メッセージを表示するには、単にプロパティに移動します。BindError

<TextBlock Text="{Binding Error}" Foreground="Red" />
<TextBlock Text="{Binding Name}" />

(もちろん、色は任意です)。

更新 >>>

IDataErrorInfoインターフェイスは、モデル/データ型クラスによって実装されます。したがって、Errorプロパティはデータ型クラスにあり (コードで示したように)、そのクラスから他のプロパティにアクセスするのと同じ方法でアクセスできます。

clsDamagedProducts instance = new clsDamagedProducts();
instance.UnitName = "Some Name";
MessageBox.Show(instance.Error);

更新 2 >>>

これらの検証エラーを取得する方法は多数あります。1 つの方法は、検証する各プロパティ名を単にインデクサー メソッドに渡し、結果を返すことです。

public string Error
{
    get
    {
        if (this["Name"] != string.Empty) return this["Name"];
        ...
        else if (this["OtherProperty"] != string.Empty) return this["OtherProperty"];
        return string.Empty;
    }
}

あなたも使用できるValidation.Errorsプロパティについて言及しましたが、それを行うには、および/またはプロパティをに設定する必要があります。これらの詳細については、MVVM記事のWPF: Validation made easy with IDataErrorInfoおよびWPF Validation with Attributes および IDataErrorInfo インターフェイスを参照してください。ValidatesOnDataErrorsNotifyOnValidationErrorTrue

個人的には、これらのプロパティまたはErrorプロパティを直接使用しないことを好みます。代わりに、派生クラスでオーバーライドされる基本クラスで名前がabstract付けられたコレクション プロパティがあります。Errors

public override ObservableCollection<string> Errors
{
    get
    {
        errors = new ObservableCollection<string>();
        errors.AddUniqueIfNotEmpty(this["Name"]);
        errors.AddUniqueIfNotEmpty(this["EmailAddresses"]);
        errors.AddUniqueIfNotEmpty(this["StatementPrefixes"]);
        return errors;
    }
}

ご覧のとおり...これにより、一度に複数のエラーを表示できます。

于 2013-10-08T08:18:21.377 に答える