UWP использует GetBindingExpression с x:Bind

Я переписываю свое приложение UWP с Binding на x: Bind. У меня есть событие TextChanged в разных текстовых полях. С Binding я мог бы использовать GetBindingExpression для обновления модели. Есть ли эквивалентный метод для x: Bind? Или как мне это сделать с помощью x:Bind?

    public void TextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        var binding = ((TextBox)sender).GetBindingExpression(TextBox.TextProperty);
        binding.UpdateSource();
    }

person SPI    schedule 01.03.2016    source источник


Ответы (3)


Я пытался сделать это раньше без успеха. Думаю пока недоступен, т.к. Bind это просто расширение разметки. Вот документация и примеры ее использования https://msdn.microsoft.com/en-us/library/windows/apps/mt204783.aspx

person RicardoPons    schedule 01.03.2016

FrameworkElement.GetBindingExpression возвращает BindingExpression, которая содержит информацию об одном экземпляре Привязка.

Так что это можно использовать только в Binding. Согласно вашему опубликованному коду, кажется, вы хотите использовать x: Bind для обновления источника при изменении текста. В Binding мы можем установить UpdateSourceTrigger на PropertyChanged, чтобы сделать следующее:

<TextBox Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="200" Margin="5" />

Но для x:Bind нет свойства UpdateSourceTrigger, и оно срабатывает только при потере фокуса. Поэтому я предлагаю вам продолжать использовать Binding в этом случае.

person Jayden    schedule 02.03.2016
comment
Этот совет почти правильный, но вводит в заблуждение в 2020 году, я не уверен, когда проблема, описанная здесь, была исправлена, даже если это была ошибка. - person Chris Schaller; 02.10.2020

Скомпилированные привязки x:Bind — это директивы, которые выполняются во время разработки для генерации кода для регистрации обработчиков событий и явной установки соответствующих свойств в обход регистрации {Binding}, которая использует отражение во время выполнения, поэтому во время выполнения нет способа обнаружить или получить дескриптор оператор привязки из x:Bind, потому что его нет.

Как частично объяснил @Jayden, в вашем конкретном случае вообще не обязательно получать привязку, так как это не необходимо вручную / явным образом вызывать обновление привязки при изменении текста, это противоречит интуиции и приводит к неожиданным результатам.

Правильный способ гарантировать, что немедленные изменения в свойстве Text объекта TextBox будут зафиксированы обратно через традиционный TwoWay {Binding} или скомпилированный TwoWay {x:Bind}, — установить свойство UpdateSourceTrigger=PropertyChanged.

в UWP и {Binding}, и {X:Bind} поддерживают UpdatteSourceTrigger, однако {X:Bind} имеет более простую реализацию с ограниченными параметрами, однако оба делают поддерживают PropertyChanged

Оба следующих варианта будут работать:

<TextBox Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
         Width="200" 
         Margin="5" />
<TextBox Text="{x:Bind VM.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
         Width="200" 
         Margin="5" />

ЕДИНСТВЕННЫЙ раз, когда вы вручную обновляете привязку, это если ваш оператор привязки установил UpdateSourceTrigger в Explicit.

Причина, по которой вам не следует пытаться обновить привязку вручную, заключается в том, что это будет конфликтовать с оператором привязки, особенно если для привязки намеренно задано значение UpdateSourceTrigger=LostFocus. В этом случае ваш обработчик событий по-прежнему будет обновлять привязку при изменении текста, когда или если это станет проблемой для разработчиков в будущем, они не будут думать о явной обработке события изменения текста.

В рамках перехода на скомпилированные привязки x:Bind и с учетом того, что они могут использоваться для любых привязок, вам следует внимательно просмотреть все вызовы GetBindingExpression() в коде и попытаться исключить их, поскольку GetBindingExpression() больше не является надежным механизмом для определения того, был настроен DependencyProperty, или получить оператор привязки для DependencyProperty во время выполнения.

Мне известен один стандартный элемент управления (NumberBox), который не поддерживает должным образом UpdateSourceTrigger=PropertyChanged, однако из-за того, что вы не можете определить, использовалась ли скомпилированная привязка для привязки свойства, необходимого другим решениям которые будут использоваться для изменения ожидаемых нами изменений, см. этот пост для решения NumberBox

person Chris Schaller    schedule 02.10.2020