Валидация путем сравнения свойств одного объекта с другим - PullRequest
0 голосов
/ 28 ноября 2011

Вот что у меня есть:

В представлении есть элемент управления вкладками с двумя вкладками (sys1 и sys2), каждая с одинаковыми текстовыми полями, которые связаны со свойствами соответствующих объектов:

sys1:

<TextBox Text="{Binding sys1.Serial, ValidatesOnExceptions=True, NotifyOnValidationError=True}" />

sys2:

<TextBox Text="{Binding sys2.Serial, ValidatesOnExceptions=True, NotifyOnValidationError=True}" />

Используя некоторую форму проверки, я хотел бы сравнить два значения и отобразить ошибку (красная граница в порядке), еслизначения не совпадают.

Я уже использовал IDataErrorInfo, но я не уверен, возможен ли этот тип проверки.

Примечание: привязка напрямую к сущности«правильно» - это обсуждение другого места и времени.Просто знайте, что это командный проект, и стандарты наших команд должны быть связаны с организацией, поэтому я не могу изменить это, если у меня нет веской причины.Возможно, если это невозможно проверить при привязке непосредственно к сущности, у меня может быть достаточно веской причины изменить это.

Спасибо

Ответы [ 2 ]

1 голос
/ 28 ноября 2011

Я обычно выставляю делегата проверки из моей модели, который моя ViewModel может использовать для присоединения проверки бизнес-правил к моделям.

Например, ViewModel, содержащий ваши объекты, может выглядеть так:

public ParentViewModel()
{
    sys1.AddValidationErrorDelegate(ValidateSerial);
    sys2.AddValidationErrorDelegate(ValidateSerial);
}

private string ValidateSerial(object sender, string propertyName)
{
    if (propertyName == "Serial")
    {
        if (sys1.Serial == sys2.Serial)
            return "Serial already assigned";
    }
    return null;
}

Идея состоит в том, что ваш Model должен содержать только необработанные данные, поэтому он должен проверять только необработанные данные. Это может включать проверку таких вещей, как максимальная длина, обязательные поля и допустимые символы. Бизнес-логика, которая включает в себя бизнес-правила, должна быть проверена в ViewModel, и это позволяет это сделать.

Реальная реализация моего IDataErrorInfo в классе Model будет выглядеть следующим образом:

#region IDataErrorInfo & Validation Members

/// <summary>
/// List of Property Names that should be validated
/// </summary>
protected List<string> ValidatedProperties = new List<string>();

#region Validation Delegate

public delegate string ValidationErrorDelegate(object sender, string propertyName);

private List<ValidationErrorDelegate> _validationDelegates = new List<ValidationErrorDelegate>();

public void AddValidationErrorDelegate(ValidationErrorDelegate func)
{
    _validationDelegates.Add(func);
}

#endregion // Validation Delegate

#region IDataErrorInfo for binding errors

string IDataErrorInfo.Error { get { return null; } }

string IDataErrorInfo.this[string propertyName]
{
    get { return this.GetValidationError(propertyName); }
}

public string GetValidationError(string propertyName)
{
    // If user specified properties to validate, check to see if this one exists in the list
    if (ValidatedProperties.IndexOf(propertyName) < 0)
    {
        //Debug.Fail("Unexpected property being validated on " + this.GetType().ToString() + ": " + propertyName);
        return null;
    }

    string s = null;

    // If user specified a Validation method to use, Validate property
    if (_validationDelegates.Count > 0)
    {
        foreach (ValidationErrorDelegate func in _validationDelegates)
        {
            s = func(this, propertyName);
            if (s != null)
            {
                return s;
            }
        }
    }

    return s;
}

#endregion // IDataErrorInfo for binding errors

#region IsValid Property

public bool IsValid
{
    get
    {
        return (GetValidationError() == null);
    }
}

public string GetValidationError()
{
    string error = null;

    if (ValidatedProperties != null)
    {
        foreach (string s in ValidatedProperties)
        {
            error = GetValidationError(s);
            if (error != null)
            {
                return error;
            }
        }
    }

    return error;
}

#endregion // IsValid Property

#endregion // IDataErrorInfo & Validation Members

P.S. Я не вижу ничего плохого в привязке непосредственно к модели, особенно в небольших приложениях. Это может не быть подход «MVVM-пурист», однако он эффективен и требует гораздо меньше усилий, поэтому я считаю его вполне приемлемым вариантом.

0 голосов
/ 28 ноября 2011

В наборе (мутаторе) для sys1.Serial1 и sys2.Serial вы сможете получить значение другого для сравнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...