3

我有一个 DataGrid,我将它绑定到“客户”类的 ObservableCollection,实现 IDataErrorInfo。Customer 类的属性之一是int,在我的 IDataErrorInfo 实现中,我检查它是否在有效范围内,例如:-

public class Customer : IDataErrorInfo
{
    public int PercentDiscount { get; set; }

    ... other properties & methods removed for clarity

    public string this[columnName]
    {
        get
        {
            if (PercentDiscount < 0 || PercentDiscount > 10)
                return "Percent Discount is invalid";
        }
    }
}

在我的 XAML 代码隐藏中,我处理了几个事件。如果PreparingCellForEdit我存储对正在编辑的行的引用:-

private void DataGrid_PreparingCellForEdit(object sender, DataGridPreparingCellForEditEventArgs e)
{
    _rowBeingEdited = e.Row;
}

然后在这种情况RowEditEnding下,如果该行处于无效状态,我会采取一些措施(在我的情况下,我将 Customer 属性恢复为之前的“好”值):-

private void DataGrid_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
{
    if (_rowBeingEdited != null)
    {
        var errors = Validation.GetErrors(_rowBeingEdited);
        if (errors.Count > 0)
        {
            .. do something
        }
    }
}

如果用户输入的数字值未通过我的验证规则,则此方法可以正常工作,但如果用户输入非数字值,则该RowEditEnding事件永远不会触发并且单元格保持在编辑状态。我认为这是因为 WPF 无法将非数字值绑定到int属性。发生这种情况时,有什么方法可以检测/处理吗?

最后的手段是将PercentDiscount属性更改为字符串,但我试图避免沿着这条路线走。

编辑- 我刚刚发现我可以使用CellEditEnding事件而不是RowEditEnding. 但是出现了一个新问题 - 如果我在单元格中输入无效值然后按Enter,则基础属性不会更新,因此当 CellEditEnding 触发时Validation.GetErrors为空。最终结果是该行离开编辑模式,但仍然在带有红色边框的单元格中显示无效值。知道现在发生了什么吗?

4

2 回答 2

1

这可能不是一个很好的答案,尤其是因为您已经提到过它,但是我已经与 DataGrid 验证进行了一段时间的斗争,最终使我的支持值成为字符串。您会在调试器的输出窗口中注意到,当您在绑定到 int 的 DataGridColumn 中键入字母字符时会发生绑定或转换异常。

您可以通过更改 UpdateSourceTrigger 或通过在绑定和属性之间放置一个转换器来获得不同的行为,但在我使用字符串支持这些值之前,我从来没有完全得到我需要的东西。

我想您也可以尝试创建自己的从 DataGridTextColumn 派生的 DataGridNumericColumn,也许您可​​以更好地控制绑定/验证行为。

于 2013-04-12T23:51:14.510 回答
1

我努力为此找到一个好的解决方案,但我看到其他一些人弄乱了CellEditEnding事件,最后我想出了这段代码来在转换失败时恢复值:

private void CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
    if (e.EditingElement is TextBox)
    {
        var cellTextBox = (TextBox)e.EditingElement;
        var cellTextBoxBinding = cellTextBox.GetBindingExpression(TextBox.TextProperty);
        if (cellTextBoxBinding != null && !cellTextBoxBinding.ValidateWithoutUpdate())
        {
            cellTextBoxBinding.UpdateTarget();
        }
    }
}

如果值转换失败,则在编辑元素绑定上调用ValidateWithoutUpdate会返回 false,然后调用UpdateTarget 会强制将值恢复为当前的“模型”值。

于 2016-01-11T05:47:43.380 回答