WPF 数据网格:保存单击时列出所有错误

本文关键字:有错误 单击 保存 数据 数据网 网格 WPF | 更新日期: 2023-09-27 18:35:10

我正在创建一个 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
}

WPF 数据网格:保存单击时列出所有错误

我不清楚你为什么要这样做,但作为示例,你可以枚举行并像这样自己调用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>
...

您可以使用 Validation.Error Attached Event

<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显示列表条目。

相关文章: