我的设置如下:
问题在于,当我按下键盘上的Enter键时,我在上一个输入字段中提供的值不会被推送到ViewModel的基础属性。
我怀疑这与在窗口关闭之前输入字段没有丢失焦点这一事实有关(因此所有绑定都“解散”)。 为了进行比较,如果我单击“保存”按钮(而不是让Enter上的窗口处理其Click),则在属性中更新值 。 此外,如果我为按钮的Click事件添加(恐怖!恐怖!)事件处理程序,并在代码隐藏中调用button.Focus(),一切正常!
可以采取什么补救措施?
我显然不想处理任何窗口关闭事件,并且“手动”获取缺失值...这将违反整个MVVM概念: - (
有更好的建议吗?
谢谢你, 亚历
答案 0 :(得分:13)
默认情况下,TextBox
只会在失去焦点后通知其来源,其值已更改。您可以通过设置UpdateSourceTrigger=PropertyChanged
来更改绑定中的内容。这将使TextBox向其源发送更新通知,其Text将被更改,而不是仅在它失去焦点时。
如果您不想在按下任何键时发送更新通知,则可以创建AttachedProperty
以在按下Enter键时更新源。
这是我用于这种情况的AttachedProperty:
// When set to True, Enter Key will update Source
#region EnterUpdatesTextSource DependencyProperty
// Property to determine if the Enter key should update the source. Default is False
public static readonly DependencyProperty EnterUpdatesTextSourceProperty =
DependencyProperty.RegisterAttached("EnterUpdatesTextSource", typeof (bool),
typeof (TextBoxHelper),
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 += OnPreviewKeyDownUpdateSourceIfEnter;
}
else
{
sender.PreviewKeyDown -= OnPreviewKeyDownUpdateSourceIfEnter;
}
}
}
// If key being pressed is the Enter key, and EnterUpdatesTextSource is set to true, then update source for Text property
private static void OnPreviewKeyDownUpdateSourceIfEnter(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();
}
}
}
#endregion //EnterUpdatesTextSource DependencyProperty
答案 1 :(得分:3)
试试这个。
{Binding Property,UpdateSourceTrigger = PropertyChanged,Mode = OneWayToSource}
答案 2 :(得分:0)
一个简单的技巧是将焦点移离控件,例如按钮本身。您可以在按钮的Click处理程序中执行此操作,因为它将在绑定命令之前执行:
public MyView()
{
InitializeComponent();
_button.Click += delegate
{
_button.Focus();
};
}
如果您不想在视图中使用代码,则还可以在添加到按钮中的行为中执行此操作。
答案 3 :(得分:-3)
这只是一个WPF错误。 (设计或实现,我不知道。)关于焦点丢失的TextBox更新是大多数情况下的预期行为,默认按钮应该在对话框中工作。
对于解决方法,我认为使用TextBox调整是一个错误的方向。更好的解决方案是将焦点强制设置为默认按钮。