Почему настройки привязки ведут себя по-разному в .NET 4 по сравнению с .NET 3.5 - PullRequest
3 голосов
/ 17 января 2011

У меня есть приложение, которое я недавно преобразовал из проекта VS 2008.NET 3.5 в проект VS2010 .NET 4.Некоторые из диалогов WPF в проекте ведут себя по-разному после преобразования.Я хотел бы понять, что вызывает эту разницу в поведении, поэтому я могу найти и исправить другие области, которые могут теперь иметь проблемы.

Например, у меня есть диалог MVVM, который позволяет пользователю вводить вчисло.Число хранится внутри как double, и пользователь может принять диалог, только если введенный текст является действительным double.Поэтому у меня есть текстовое поле, связанное со строкой в ​​ViewModel, и кнопка OK, которая активируется только тогда, когда строка является действительным двойным числом.Соответствующий Xaml выглядит следующим образом:

<TextBox Text="{Binding ValueString, UpdateSourceTrigger=PropertyChanged}"/>
<Button IsEnabled="{Binding ValueIsValid}">OK</Button>

И ViewModel выглядит следующим образом:

class ViewModel : INotifyPropertyChanged
{
    private double actualValue;
    public string ValueString
    {
        get { return actualValue.ToString("G3"); }
        set
        {
            double doubleValue;
            if (double.TryParse(value, NumberStyles.Float, CultureInfo.CurrentCulture, out doubleValue))
            {
                actualValue = doubleValue;
                ValueIsValid = true;
                RaisePropertyChanged("ValueString");
            }
            else
            {
                ValueIsValid = false;
            }
        }
    }

    private bool valueIsValid = true;
    public bool ValueIsValid
    {
        get { return valueIsValid; }
        set
        {
            if (valueIsValid != value)
            {
                valueIsValid = value;
                RaisePropertyChanged("ValueIsValid");
            }
        }
    }

    private void RaisePropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

Это отлично работало в .NET 3.5, но когда он работает в .NET 4, он имеетпроблема, когда пользователь вводит номер.Например, если пользователь вводит «3.05555» в текстовое поле в версии .NET 3.5, все в порядке.Однако в версии .NET 4 они могут ввести 3.05 штрафа, но когда они набирают следующую «5», значение текстового поля меняется на «3.06», а затем меняется на «3.07», если они снова нажимают 5.Это как если бы значение считывалось обратно из свойства ValueString, как только оно было установлено (таким образом форматируется как «G3»), но с .NET 3.5 такого не случалось раньше.

Я просмотрел Что нового в .NET Framework 4 (включая Что нового в WPF версии 4 ), но я ничего не нашел об этом изменении.

Если вы хотите сами убедиться в этом, я создал небольшой пример решения VS2010, который можно скачать здесь .Проект BindingTest2008 был преобразован из VS 2008 и предназначен для .NET 3.5, а проект BindingTest2010 был создан в VS 2010 и предназначен для .NET 4. Код одинаков в обоих проектах, но в проекте .NET 4 есть эта проблема.

Буду признателен за любую помощь в понимании, почему это происходит.Спасибо.

Обновлено : удаление вызова RaisePropertyChanged("ValueIsValid"); не меняет поведение и ввод неправильного номера (например, "3.1a") не заменяется последним последнимдействительное число (например, «3.1» в этом случае).Также числа могут быть введены с большей точностью, чем 3 значащие цифры.Например, «3.0545555» - проблема возникает только тогда, когда набранная вами вещь вызывает округление 3-й значащей цифры.

Ответы [ 2 ]

5 голосов
/ 19 января 2011

Причина этого различия в поведении:

В 3.5 привязка будет записывать новое значение обратно в источник после каждого нажатия клавиши, без изменения текста TextBox.Но этот текст может не точно представлять значение источника, возможно, потому, что он не включает форматирование и преобразование, или потому что источник изменил значение (в параметре-установщике свойств) на что-то другое.Это приводило к частым и яростным жалобам - люди хотели, чтобы TextBox показывал значение источника, точно так же, как TextBlock, если бы он был связан с тем же свойством с теми же конвертерами и форматированием.Пользовательский интерфейс должен отображать то, что на самом деле находится в данных, а не то, что набрал конечный пользователь.

Чтобы исправить этот класс ошибок в 4.0, привязка теперь применяет форматирование и преобразование к новому значению источника после каждого обновления.(Привязки LostFocus уже делали это в 3.5.) Теперь TextBox показывает, что находится в данных, но это может усложнить набор текста пользователем.

Мы планируем улучшить этот сценарий в следующем выпуске как минимум двумя способами: 1. Когда текст TextBox заменяется измененной строкой, точка вставки (курсор), которая работала для старой строки, может больше не быть правильной для новой строки.Эвристика, которая угадывает, куда поместить курсор, может быть улучшена.2. Привязки предоставляют способ обновления LostFocus (или явного) с частичной проверкой после каждого нажатия клавиши.Форматирование / преобразование применяется только при смене фокуса, но пользователь получает сообщение о проверке после каждого нажатия клавиши.

  • Сэм (команда WPF)

От " Изменено поведение с .Net 3.5 на .Net 4.0 форматирования WPF TextBox, когда PropertyChanged используется в качестве UpdateSourceTrigger"

2 голосов
/ 17 января 2011

Похоже, проблема в этой строке:

 get { return actualValue.ToString("G3"); }

Версия .Net 4 работает корректно, поскольку значение форматируется с использованием строки формата «G3», что означает, что в строке результата будет 3 значащих цифры (3.055 становится 3.06).

Разница между 3,5 и 4 в том, что, видимо, система привязки была немного изменена. В 3.5, когда вызывается установщик свойства, и он вызывает событие PropertyChanged, привязка не переоценивается (геттер не вызывается). В то время как в .Net 4 после запуска события PropertyChanged привязка переоценивается, т. Е. Вызывается получатель свойства IS, и значение, возвращаемое получателем, отображается в текстовом поле.

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