Как достигнуть сброшенный фокусом для обновления BindingSource TextBox перед любым действием

Вы пропустили тот.

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

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

10
задан Simon D. 15 July 2009 в 19:43
поделиться

3 ответа

Может быть, нехорошо отвечать на собственные вопросы, но я думаю, что этот ответ больше подходит для вопроса, чем другие, и поэтому стоит написать. Конечно, это было также из-за того, что я недостаточно четко описал проблему.

Наконец, в качестве быстрого, а не грязного доказательства концепции, я работал над этим следующим образом: Событие LostFocus никогда не запускается в TextBox, когда я переключаю вкладку. Следовательно, привязка не обновляется, и введенное значение теряется, поскольку при обратном переключении привязка обновляется из источника. Но запускается событие PreviewLostFocus-Event, поэтому я подключился к этой крошечной функции, которая вручную запускает обновление источника привязки:

private void BeforeFocusLost(object sender, KeyboardFocusChangedEventArgs e)
{
  if (sender is TextBox) {
    var tb = (TextBox)sender;

    var bnd = BindingOperations.GetBindingExpression(tb, TextBox.TextProperty);

    if (bnd != null) {
      Console.WriteLine(String.Format("Preview Lost Focus: TextBox value {0} / Data value {1} NewFocus will be {2}", tb.Text, bnd.DataItem, e.NewFocus));
      bnd.UpdateSource();
    }
    Console.WriteLine(String.Format("Preview Lost Focus Update forced: TextBox value {0} / Data value {1} NewFocus will be {2}", tb.Text, bnd.DataItem, e.NewFocus));
  }
}

Вывод в соответствии с цепочкой событий с PreviewLostFocus, LostFocus (оба из TextBox) и SelectionChanged ( from TabControl) будет выглядеть так:

Preview Lost Focus: TextBox value Smith123456 / Data value John Smith123 NewFocus будет System.Windows.Controls.TabItem Заголовок: Питер Миллер Содержимое: Питер Миллер Предварительный просмотр потерянного фокуса Обновление принудительно: значение TextBox Smith123456 / значение данных John Smith123456 NewFocus будет System.Windows.Controls.TabItem Заголовок: Питер Миллер Содержимое: Питер Миллер Выбор изменен с System.Object [] на System.Object [] Предварительный просмотр Lost Focus: значение TextBox Miller / значение данных Peter Miller NewFocus будет System.Windows.Controls.TextBox: Peter Предварительный просмотр потерянного фокуса. Обновление принудительно: значение TextBox Miller / значение данных Peter Miller NewFocus будет System.Windows.Controls.TextBox: Peter Lost Focus со значением Miller

Мы видим, что LostFocus происходит только в конце, но не перед изменением TabItem. Все же мне кажется это странным, возможно, ошибка в WPF или в стандартных шаблонах элементов управления. Спасибо всем за ваши предложения, извините, я не смог подписать их как ответы, так как они не решили проблему потери записей при смене вкладки.

3
ответ дан 4 December 2019 в 04:01
поделиться

Вы можете написать стиль, ориентированный на все текстовые поля, в котором у вас будет EventSetter для событий GotFocus или GotKeyboardFocus, а также для дополнительных событий LostFocus. В обработчике, связанном с событиями GotFocus, вы должны установить для логической переменной canSave значение false, а в обработчике LostFocus вы вернете значение true. Все, что вам нужно сделать, это проверить перед сохранением, позволяет ли ваша переменная тоже. Если нет, вы можете уведомить пользователя или просто переключить фокус с текстового поля на что-то другое. Таким образом, триггер обновления привязки для редактируемого в данный момент текстового поля сработает соответствующим образом, когда его фокус будет потерян.

1
ответ дан 4 December 2019 в 04:01
поделиться

Возможно установить свойство UpdateSourceTrigger привязки:

<TextBox Text="{Binding FirstName, UpdateSourceTrigger=Explicit}"/>

Я не уверен, что это то, что вы ищете.

0
ответ дан 4 December 2019 в 04:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: