проблемы с правилом проверки

Я пытаюсь получить правило проверки для возврата ошибки. Я реализовал IDataErrorInfo в своей модели, которая содержит свойства моего бизнес-объекта и сообщения, возвращаемые в случае сбоя проверки события. Я также создал правило проверки. Проблема в том, что правило проверки срабатывает (сделано закладкой), но ссылка IDataErrorInfo в правиле никогда не содержит ошибки, даже если реализация IDataErrorInfo моей модели генерирует ее. Сетка данных определенно показывает, что произошла ошибка проверки.

Я проверил это, заставив правило и модель возвращать два разных сообщения, и версия модели всегда возвращается. Это похоже на то, что мое правило не может видеть, что находится в объекте IDataErrorInfo, или оно просто создает новый его экземпляр.

Сетка данных:

<DataGrid ItemsSource="{Binding Path=ProjectExpenseItemsCollection}" AutoGenerateColumns="False" 
    Name="dgProjectExpenseItems" RowStyle="{StaticResource RowStyle}" 
    SelectedItem="{Binding Path=SelectedProjectExpenseItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
    CanUserDeleteRows="True" CanUserAddRows="True">
    <DataGrid.RowValidationRules>
        <vr:RowDataInfoValidationRule ValidationStep="UpdatedValue" />
    </DataGrid.RowValidationRules>
    <DataGrid.Columns>
        <DataGridTextColumn Header="Item Number" 
            Binding="{Binding ItemNumber, Mode=TwoWay, 
            UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />
    </DataGrid.Columns>
</DataGrid>

Правило проверки:

Объект "idei" не нулевой, но idei.Error всегда является строкой нулевой длины ("")

public class RowDataInfoValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        BindingGroup bindingGroup = (BindingGroup)value;
        IDataErrorInfo idei = bindingGroup.Items[0] as IDataErrorInfo;
        string error = (idei != null) ? idei.Error : null; 
        return (string.IsNullOrEmpty(error)) ? ValidationResult.ValidResult : new ValidationResult(false, error + ": ValidationRule");
    }
}

Модель/Бизнес-объект:

public class ProjectExpenseItemsBO : IDataErrorInfo, IEditableObject, INotifyPropertyChanged
{
    public string ItemNumber { get; set; }

    public ProjectExpenseItemsBO() {}

    // string method
    static bool IsStringMissing(string value)
    {
        return String.IsNullOrEmpty(value) || value.Trim() == String.Empty;
    }

    #region IDataErrorInfo Members

    public string Error
    {
        get { return this[string.Empty]; }
    }

    public string this[string propertyName]
    {
        get
        {
            string result = string.Empty;
            if (propertyName == "ItemNumber")
            {
                if (IsStringMissing(this.ItemNumber))
                {
                    result = "Item number cannot be empty-IDataError!";
                }
            }

            return result;
        }
    }

    #endregion
}

person steveareeno    schedule 28.07.2010    source источник


Ответы (1)


Объект IDataErrorInfo, который получает правило, будет экземпляром вашего объекта ProjectExpenseItemsBO. Единственное свойство, которое вы проверяете, это Error, которое вы реализовали для возврата this[string.Empty], которое всегда будет возвращать string.Empty. Возможно, вы захотите либо изменить реализацию свойства Error, чтобы просмотреть все ошибки в объекте, либо сделать так, чтобы RowDataInfoValidationRule перебирал свойства и получал сообщение об ошибке для каждого из них через индексатор.

Вы получаете ошибки проверки от модели, потому что ваша привязка к ItemNumber имеет ValidatesOnDataErrors, установленную в True, поэтому платформа вызовет индексатор с именем свойства ItemNumber и получит ваше сообщение об ошибке.

person Quartermeister    schedule 29.07.2010
comment
это имеет смысл, и я чувствую себя немного глупо, не замечая этого (новичок). Я добавил код, необходимый для передачи ошибки, и он работает! Что касается вашего второго ответа, хотя мой VR может получить доступ к ошибке, dg все еще ищет в IDEI в модели свое сообщение и результат проверки? Как я могу заставить правило переопределять IDEI в этом случае? Я пытаюсь заставить VR сбросить ошибку проверки в dg, когда ошибка будет исправлена, но я могу сделать это, только если я отсортирую или обновлю dg. Я думал, что установка VR в качестве результата ValidResult устранит ошибку. Кстати, спасибо! - person steveareeno; 29.07.2010
comment
Позвольте мне кое-что исправить. Я не обязательно хочу переопределить ошибку из IDEI в модели - это было действительно для целей тестирования - я хочу сделать, это очистить ошибку проверки в сетке, когда пользователь исправляет ошибку, что не происходит, если я не сортирую или обновить dg. - person steveareeno; 29.07.2010
comment
Хорошо, теперь я понял. поскольку для столбца в моем dg для ValidatesOnDataErrors установлено значение true, он будет игнорировать результат VR. Я удалил его из колонки, и теперь все работает нормально. Я думал, что смогу использовать их в сочетании друг с другом, но, похоже, это либо/или. Это было все о очистке ошибки от dg, когда она была исправлена. В этом случае кажется, что VR может это сделать, а IDEI не может, по крайней мере, без обновления dg. - person steveareeno; 29.07.2010
comment
Еще кое-что, квартирмейстер. Я действительно хочу поблагодарить вас за ваш ответ! Я пытаюсь решить эту проблему уже около двух или трех недель. - person steveareeno; 29.07.2010
comment
@steveareeno: я думаю, что в DataGrid есть некоторые ошибки при обработке проверки. См. wpf.codeplex.com/wikipage?title=Validation для описания проблемы. . В этой статье, кажется, есть некоторые обходные пути, но я на самом деле их не пробовал: codeproject .com/KB/WPF/WPFDataGridExamples.aspx#validation. - person Quartermeister; 29.07.2010
comment
Спасибо. Я взглянул на него и помню, что читал то же самое где-то еще (об использовании значения RawProposed). Я использую VS 2010, который, как я понимаю, имеет свой собственный dg (по сравнению с использованием набора инструментов). Однако не уверен, что проблема исправлена ​​в этой версии. - person steveareeno; 29.07.2010