#c# #mvvm #prism #propertychanged #access-keys
#c# #mvvm #prism #propertychanged #ключи доступа
Вопрос:
Не совсем уверен, как решить эту проблему:
У меня есть кнопка «Сохранить», к которой прикреплены ключи доступа … но, если я ввожу что-то в текстовое поле и нажимаю клавиши доступа для сохранения, текстовое поле не обновляет мою viewmodel, потому что оно никогда не теряло фокус. Есть ли способ решить эту проблему, помимо изменения UpdateSourceTrigger на PropertyChanged?
Комментарии:
1. Почему вы не можете изменить триггер на PropertyChanged?
2. Это потребовало бы, чтобы ВСЕ свойства делали это, и это приводит к множеству уведомлений, которые кажутся ненужными… Кроме того, что, если кто-то захочет отменить свои изменения…
Ответ №1:
Ваша проблема заключается в UpdateSourceTrigger="LostFocus"
Это значение используется по умолчанию для текстовых полей и означает, что текстовое поле обновит свое привязанное значение только тогда, когда оно потеряет фокус
Один из способов принудительно обновить его без настройки UpdateSourceTrigger="PropertyChanged"
— подключиться к событию нажатия клавиши, и если комбинация клавиш вызывает сохранение, сначала вызовите UpdateSource()
Вот прикрепленное свойство, которое мне нравится использовать, когда клавиша Enter должна обновлять исходный код.
Он используется следующим образом:
<TextBox Text="{Binding Name}"
local:TextBoxProperties.EnterUpdatesTextSource="True" />
и прикрепленное определение свойства выглядит следующим образом:
public class TextBoxProperties
{
public static readonly DependencyProperty EnterUpdatesTextSourceProperty =
DependencyProperty.RegisterAttached("EnterUpdatesTextSource", typeof(bool), typeof(TextBoxProperties),
new PropertyMetadata(false, EnterUpdatesTextSourcePropertyChanged));
// Get
public static bool GetEnterUpdatesTextSource(DependencyObject obj)
{
return (bool)obj.GetValue(EnterUpdatesTextSourceProperty);
}
// Set
public static void SetEnterUpdatesTextSource(DependencyObject obj, bool value)
{
obj.SetValue(EnterUpdatesTextSourceProperty, value);
}
// Changed Event - Attach PreviewKeyDown handler
private static void EnterUpdatesTextSourcePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var sender = obj as UIElement;
if (obj != null)
{
if ((bool)e.NewValue)
{
sender.PreviewKeyDown = OnPreviewKeyDown_UpdateSourceIfEnter;
}
else
{
sender.PreviewKeyDown -= OnPreviewKeyDown_UpdateSourceIfEnter;
}
}
}
// If key being pressed is the Enter key, and EnterUpdatesTextSource is set to true, then update source for Text property
private static void OnPreviewKeyDown_UpdateSourceIfEnter(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
if (GetEnterUpdatesTextSource((DependencyObject)sender))
{
var obj = sender as UIElement;
BindingExpression textBinding = BindingOperations.GetBindingExpression(
obj, TextBox.TextProperty);
if (textBinding != null)
textBinding.UpdateSource();
}
}
}
}
Комментарии:
1. Хороший трюк, но недостатком является то, что его сложнее использовать, чем изменение моих элементов управления для сохранения с помощью PropertyChanged вместо LostFocus. Думаю, я просто хотел бы, чтобы Microsoft выполнила LostFocus при выполнении ключа доступа. В принципе, выполнение ключа доступа должно было быть таким же, как фактическое использование мыши для нажатия на кнопку. Хотя мне нравится этот трюк … вздох