Простая привязка текста TextBox не работает WPF - PullRequest
0 голосов
/ 08 мая 2018

Мы конвертируем приложение из Silverlight в WPF. Это довольно сложное приложение, но совместное использование кода составляет около 95%. XAML почти такой же, за исключением определений пространства имен XML и т. Д. Около 90% приложения сейчас работает, но есть несколько вопиющих проблем, которые меня озадачивают. Одним из них является этот обязательный вопрос.

У нас есть объект модели с именем TaskInfo. У него есть свойство с именем TaskNo. в Silverlight и WPF мы привязываем это свойство следующим образом

<TextBox IsReadOnly="True" Grid.Column="0"  Grid.Row="0" Margin="1" Text="{Binding Path=TaskNo}" Height="28"  Background="#CAECF4" VerticalAlignment="Center" VerticalContentAlignment="Center"  />

И в WPF, и в Silverlight TaskNo отображается правильно, когда модель TaskInfo впервые задана как DataContext. В Silverlight, если мы создадим новый TaskInfo, отправим его на сервер для сохранения и вернем модель с новым TaskNo, TaskNo будет успешно отображено. Но в WPF он просто отображает 0, когда сохраненное TaskInfo возвращается с сервера. Существует некоторая проблема с привязкой. Это ошибка привязки, которую я вижу в окне вывода:

System.Windows.Data Information: 10: Невозможно получить значение, используя привязка и не существует действительного запасного значения; вместо этого используется значение по умолчанию. BindingExpression: Path = TaskNo; DataItem = NULL; целевой элемент 'TextBlock' (Name = ''); Целевое свойство - «Текст» (тип «Строка»)

Я проверил визуальное дерево, и DataContext TextBox, как и ожидалось, установлен в TaskInfo.

Итак, я отключил привязку и попробовал этот код. Это обработчик событий для DataContextChanging в TextBox. Этот код работает нормально. Когда новая задача сохраняется и возвращается, TaskNo успешно отображается здесь:

    private void TaskNoBox_DataContextChanging(object sender, DependencyPropertyChangedEventArgs e)
    {
        var task = TaskNoBox.DataContext as TaskInfo;
        if (task == null)
        {
            throw new Exception("Ouch!");
        }
        TaskNoBox.Text = task.TaskNo.ToString();
    }

Для дальнейшей отладки этой проблемы я добавил этот обработчик события для события GotFocus в текстовое поле. Итак, после того, как задача была сохранена на стороне сервера и возвращена и установлена ​​как DataContext, я щелкаю внутри элемента управления, чтобы запустить этот обработчик событий. Когда я выполняю этот код, я вижу, что DataContext является правильным и имеет правильное значение TaskNo. Вызов этого кода по-прежнему не вызывает привязку.

    private void TextBox_GotFocus(object sender, RoutedEventArgs e)
    {
        var textBox = (TextBox)sender;
        var be = textBox.GetBindingExpression(TextBox.TextProperty);
        be.UpdateSource();
        be.UpdateTarget();
    }

TextBox Свойство привязки текста: enter image description here

DataContext свойств TextBox: enter image description here

Как понять эту ошибку привязки? Каковы связи между Silverlight и WPF? Нужен ли какой-то обходной путь? Почему переплет не работает?

1 Ответ

0 голосов
/ 08 мая 2018

Привязка в WPF никогда не обновляется, если предыдущий DataContext эквивалентен новому DataContext в соответствии с методом Equals.

Разница между Silverlight и WPF заключается в том, что при изменении DataContext WPF, похоже, использует метод Equals для оценки разницы между объектами, а Silverlight использует ссылку. Это означает, что WPF такой же, как Xamarin.Forms.

Я попробовал этот код, и он заставляет TaskNo отображаться правильно. Я думаю, что происходит, потому что предыдущий DataContext был эквивалентен новому DataContext при вызове Equals. Итак, это решает проблему.

    private async void TaskPageHeader_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        TaskNoBox.DataContext = new object();
        TaskNoBox.DataContext = CurrentTask;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...