Binding vs x: Bind: Почему представление не обновляется при использовании Binding? - PullRequest
0 голосов
/ 12 декабря 2018

Я разрабатываю приложение UWP, использующее парадигму MVVM.Мое представление содержит простой TextBox, свойство Text которого привязано к соответствующему свойству ViewModel:

<TextBox Text="{Binding Path=Radius, Mode=TwoWay}"/>

Естественно, я назначил свою ViewModel для DataContext:

public sealed partial class ExamplePage : Page
{
    private ExamplePageVM viewModel;

    public ExamplePage()
    {
        this.InitializeComponent();
        viewModel = new ExamplePageVM();
        DataContext = viewModel;
    }
}
страницы.

В ViewModel я выполняю некоторую проверку ввода, т. Е. Если пользователь вставляет недопустимое значение с плавающей запятой в TextBox, я хочу сбросить TextBox на значение по умолчанию (например, ноль):

class ExamplePageVM : INotifyPropertyChanged 
{
    public event PropertyChangedEventHandler PropertyChanged;
    private float radius;

    public string Radius
    {
        get => radius.ToString();
        set
        {
            if (radius.ToString() != value)
            {
                if (!float.TryParse(value, out radius)) radius = 0;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Radius)));
            }
        }
    }
}

Изменение значения в TextBox приводит к тому, что установщик вызывается так, как задумано.Кроме того, событие PropertyChanged вызывается соответственно.Тем не менее, TextBox по-прежнему содержит недопустимые данные после завершения выполнения установки, что означает, что представление не обновляется правильно.

Согласно первому комментарию к этой записи , решение этой проблемы заключается в использовании <TextBox Text="{x:Bind viewModel.Radius, Mode=TwoWay}"/> вместо подхода Binding, показанного выше.Почему это так?В чем разница между Binding и x:Bind в этой самой ситуации?

Ответы [ 2 ]

0 голосов
/ 12 декабря 2018

Возможно, вы захотите установить UpdateTrigger самостоятельно, так как TextBox обычно обновляет источник, когда вызывается потерянный фокус.

Вы можете изменить поведение UpdateSourceTrigger = PropertyChanged.

<TextBox Text="{x:Bind AnswerText, UpdateSourceTrigger=PropertyChanged}"/>

<TextBox Text="{Binding AnswerText, UpdateSourceTrigger=PropertyChanged}"/>

Если это не работает, возможно, вы захотите запретить ввод данных, отличный от цифр с событием keydown.Который вы могли бы передать в пользовательский элемент управления для повторного использования.

Надеюсь, это поможет.

0 голосов
/ 12 декабря 2018

Привязка к TextBox.Text является довольно частным случаем, поскольку Microsoft приняла решение, где наиболее распространенный сценарий заключается в том, что привязка должна обновляться, когда элемент управления теряет фокус, в отличие от каждого входного текста.менять.Это позволяет 2 вещи:

  • несколько более эффективная обработка больших текстов
  • защита входящего пользовательского ввода от изменения приложением

В отсутствиеобщедоступный исходный код UWP, возможно, разработчики MS могут предоставить вам более надежную информацию, но даже сравнение изменений в связанном источнике с прямым отслеживанием EditBox.TextProperty через DependencyObject.RegisterPropertyChangedCallback заставляет вас ожидать, что вместо этогоИз обычной прямой привязки к изменениям свойства зависимости на самом деле в TextBox реализована дополнительная реализация типа «человек посередине», которая обрабатывает, как и когда TextProperty обновления влияют и влияют на DataContext или базовый класс.свойства, связанные с {Binding} или {x:Bind}.

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

Теперь в вашем тестовом сценарии вы пытаетесь проверить и, возможно, изменить значение свойства в связанном источнике данных, ожидая, что TextBox отобразит требуемое значение, что и происходит.с {x:Bind}, но не с {Binding}.

Очевидно, вы нашли сценарий, в котором реализации {x:Bind} и {Binding} ведут себя по-разному.Я сделал те же тесты и полностью подтвердил ваши выводы.

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