1

我正在创建一个 WPF 应用程序,它将使用我的业务对象实现的 IDataErrorInfo 数据验证。现在,当用户单击保存按钮时,我想在消息框中向用户列出所有验证错误。如何实现这一目标?

我的数据网格是:

  <my:DataGrid Name="dgReceiveInventory" RowStyle="{StaticResource RowStyle}"  ItemsSource="{Binding}" GotFocus="dgReceiveInventory_GotFocus"  CanUserDeleteRows="False" CanUserReorderColumns="False" CanUserResizeColumns="False" CanUserResizeRows="False" CanUserSortColumns="False"  RowHeight="23"  SelectionUnit="Cell"   AutoGenerateColumns="False" Margin="12,84,10,52"  BeginningEdit="dgReceiveInventory_BeginningEdit">

        <my:DataGrid.Columns>

            <!--0-Product Column-->
            <my:DataGridTemplateColumn Header="Product Name" Width="200">
                <my:DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Style="{StaticResource TextBlockInError}" Text="{Binding ProductName,ValidatesOnDataErrors=True}"  ></TextBlock>
                    </DataTemplate>
                </my:DataGridTemplateColumn.CellTemplate>
                <my:DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <TextBox x:Name="txtbxProduct"  Text="{Binding Path=ProductName,UpdateSourceTrigger=LostFocus,ValidatesOnDataErrors=True}"  TextChanged="txtbxProduct_TextChanged" PreviewKeyDown="txtbxProduct_PreviewKeyDown" >
                                    </TextBox>
                    </DataTemplate>
                </my:DataGridTemplateColumn.CellEditingTemplate>
            </my:DataGridTemplateColumn>

            <!--1-Purchase Rate Column-->
            <my:DataGridTextColumn Header="Purchase Rate" Width="100" Binding="{Binding PurchaseRate}" IsReadOnly="True"></my:DataGridTextColumn>

            <!--2-Avaialable Qty Column-->
            <my:DataGridTextColumn Header="Stock"  Binding="{Binding AvailableQty}" IsReadOnly="True" Visibility="Hidden"></my:DataGridTextColumn>


            <!--4-Amount Column-->
            <my:DataGridTextColumn Header="Amount" Width="100"  Binding="{Binding Amount}" ></my:DataGridTextColumn>
        </my:DataGrid.Columns>
    </my:DataGrid>

我的对象是:

 class clsProducts : INotifyPropertyChanged, IDataErrorInfo
{
    private string _ProductName;
    private decimal _PurchaseRate;
    private int _AvailableQty;
    private int _Qty;
    private decimal _Amount;

    #region Property Getters and Setters

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

    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");
        }
    }



    #endregion

    #region IDataErrorInfo Members

    public string Error
    {
        get
        {
           return "";

        }

    }

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

            if (name == "ProductName")
            {
                if (this._ProductName != null)
                {
                    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

2 回答 2

2

我不清楚您为什么要这样做,但作为示例,您可以Validate像这样枚举行并自行调用方法:

private void Save_Click(object sender, RoutedEventArgs e) {

    // create validation object 
    RowDataInfoValidationRule rule = new RowDataInfoValidationRule();

    StringBuilder builder = new StringBuilder();

    // enumerate all rows
    for (int i = 0; i < dgReceiveInventory.Items.Count; i++) {
        DataGridRow row = (DataGridRow) dgReceiveInventory.ItemContainerGenerator.ContainerFromIndex(i);

        // validate rule
        ValidationResult res = rule.Validate(row.BindingGroup, null);

        if (!res.IsValid) {
            // collect errors 
            builder.Append(res.ErrorContent);
        }
    }

    //show message box
    MessageBox.Show(builder.ToString());
}

如果你有

<DataGrid>
            <DataGrid.RowValidationRules>
                <local:RowDataInfoValidationRule ValidationStep="UpdatedValue" />
            </DataGrid.RowValidationRules>
...
于 2013-10-14T10:07:20.543 回答
0

您可以使用Validation.Error 附加事件

<Window Validation.Error="Window_Error">

保存NotifyOnValidationError设置为 true的绑定的所有验证错误

Text="{Binding ProductName, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"

在一个List

public List<ValidationError> ValidationErrors = new List<ValidationError>();

private void Window_Error(object sender, ValidationErrorEventArgs e)
{
    if (e.Action == ValidationErrorEventAction.Added)
        ValidationErrors.Add(e.Error);
    else
        ValidationErrors.Remove(e.Error);
}

然后MessageBox在保存按钮单击处理程序中显示列表条目。

于 2013-10-14T10:06:39.997 回答