проверка данных с использованием проблем IDataErrorInfo и MVVM Pattern - PullRequest
1 голос
/ 07 июня 2011

У меня возникла странная проблема при проверке данных с помощью IDataErrorInfo в приложении WPF MVVM, что я делаю так:

свойство, которое нужно проверить

public Decimal GlassPrice
    {
        get
        {
            return _GlassPrice;
        }
        set
        {
            if (_GlassPrice != value)
            {
                _GlassPrice = value;
                OnPropertyChanged("GlassPrice");
                CarName = allPropertiesValid.ToString();
            }
        }
    }

"Iобъяснит последнюю строку в вышеупомянутой функции «Set» CarName = .. и т. д. позже », затем переменную bool со значением по умолчанию false, чтобы представить, являются ли все проверяемые свойства истинными, используемыми в функции canExecute.

public bool allPropertiesValid
    {

        get { return _allPropertiesValid; }
        set
        {
            if (_allPropertiesValid != value)
            {
                _allPropertiesValid = value;
                OnPropertyChanged("allPropertiesValid");
            }
        }
    }

затем словарь для хранения пар имен свойств со значением bool, как показано ниже

 validAllProperties = new Dictionary<string, bool>();
 validAllProperties.Add("GlassPrice", false);

, затем, конечно, метод для проверки свойства следующим образом

private string validateGlassPrice()
    {
        if (GlassPrice <= 0)
        {
            return "price can't be 0 nor a minus value ";
        }
        else
        {
            return String.Empty;
        }   
    }

затем на реализацию IDataErrorInfo

string IDataErrorInfo.this[string columnName]
    {
        get
        {
            string error = String.Empty;
            switch (columnName)
            {
                case "GlassPrice":
                error = validateGlassPrice();
                validAllProperties["GlassPrice"] = String.IsNullOrEmpty(error) ? true : false;
                validateAllProperties();
                return error;
                default:
                throw new ApplicationException("Wrong Property name being validated");
            }

        }
    }

наконец, метод для установки конечного значения "allPropertiesValid" зависит от значений bool в словаре

private void validateAllProperties()
    {
        foreach (bool isValid in validAllProperties.Values)
        {
            if (isValid == false)
            {
                allPropertiesValid = false;
                return;
            }
        }
        allPropertiesValid = true;
    }

CarName Я сказал, что япозже будет объяснено, что это свойство привязано к textBox, и теперь я использовал его для отслеживания значения «allPropertiesValid» во время выполнения, поэтому я заставляю метод canExecute возвращать «allPropertiesVali».d "и зависит от того, будет ли кнопка, связанная с командой, включена / отключена, этот сценарий просто работает нормально, я сделал 3 или 4 формы, используя его, и они работают отлично, однако в данном конкретном случае это не так,после пересмотра выясняется, что проблема заключается только в этом конкретном свойстве «GlassPrice», я отключил все проверки для других свойств и просто сохранил это, что происходит сейчас: при вводе 1 в качестве значения Carname дает мне falseа кнопка теперь включена ??кнопка никогда не должна быть включена, пока значение метода CanExecute равно false, затем я добавляю ноль к 1, и они становятся равными 10, затем она превращается в True и остается равной True независимо от изменения значений в textBox, даже если я ввелнедействительные данные, такие как 0 или ноль, они остаются верными, и кнопка всегда включена ??Я часами сидел, пытаясь решить эту проблему. Надеюсь, кто-нибудь может мне помочь

Заранее спасибо

Редактировать: Ну, теперь проблема в том, как проверить десятичность, когда TextBox пуст??, GlassPrice имеет значение Decimal и Decimal не будет принимать значения NULL, следующий метод проверяет GlassPrice на наличие 0 или минус, но не NULL или не пусто

private string validateGlassPrice()
    {
        if (GlassPrice <= 0)
        {
            return "price can't be 0 nor a minus value ";
        }
        else
        {
            return String.Empty;
        }   
    }

1 Ответ

1 голос
/ 07 июня 2011

Я не вижу ничего явно неправильного в том, что вы написали.Вот несколько советов, которые могут помочь вам найти проблему:

Во-первых, поведение, которое вы хотите увидеть (кнопка включена / отключена), зависит от того, оценивается ли CanExecute и возвращает ли правильное значение.Это на самом деле происходит?Хороший способ выяснить это - записывать сообщения на консоль с помощью метода CanExecute, например:

Console.WriteLine("CanExecute called; returning " + result);
return result;

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

Второе предложение состоит в том, чтобы вместо этого начать использовать строковые константылитералов в вашей модели взгляда.Я не вижу, что вы здесь допустили ошибку, но код, который вы разместили, использует строковый литерал "GlassPrice" в трех разных местах.Если что-то из этого будет написано с ошибками, ваш код не будет работать так, как вы этого не ожидаете.

Наконец, две стилистические проблемы - они не являются источником вашей проблемы, но они упростят ваш код.Это:

validAllProperties["GlassPrice"] = String.IsNullOrEmpty(error) ? true : false;

должно быть так:

validAllProperties["GlassPrice"] = String.IsNullOrEmpty(error);

и это:

foreach (bool isValid in validAllProperties.Values)
{
    if (isValid == false)
    {
        allPropertiesValid = false;
        return;
    }
}
allPropertiesValid = true;

может быть так же просто, как это:

allPropertiesValid = validAllProperties.Values.All(x => x);
...