在Enter上绑定TextBox
TextBox
上的默认数据绑定是TwoWay
,它仅在TextBox
失去焦点时才将文本提交给属性。
当按下TextBox
上的Enter键时,是否有任何简单的XAML方法可以使数据绑定发生? 我知道在后面的代码中很容易做到,但想象一下,如果这个TextBox
是在一些复杂的DataTemplate
。
您可以通过创建一个附加行为来使自己成为纯粹的XAML方法。
像这样的东西:
public static class InputBindingsManager
{
public static readonly DependencyProperty UpdatePropertySourceWhenEnterPressedProperty = DependencyProperty.RegisterAttached(
"UpdatePropertySourceWhenEnterPressed", typeof(DependencyProperty), typeof(InputBindingsManager), new PropertyMetadata(null, OnUpdatePropertySourceWhenEnterPressedPropertyChanged));
static InputBindingsManager()
{
}
public static void SetUpdatePropertySourceWhenEnterPressed(DependencyObject dp, DependencyProperty value)
{
dp.SetValue(UpdatePropertySourceWhenEnterPressedProperty, value);
}
public static DependencyProperty GetUpdatePropertySourceWhenEnterPressed(DependencyObject dp)
{
return (DependencyProperty)dp.GetValue(UpdatePropertySourceWhenEnterPressedProperty);
}
private static void OnUpdatePropertySourceWhenEnterPressedPropertyChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
{
UIElement element = dp as UIElement;
if (element == null)
{
return;
}
if (e.OldValue != null)
{
element.PreviewKeyDown -= HandlePreviewKeyDown;
}
if (e.NewValue != null)
{
element.PreviewKeyDown += new KeyEventHandler(HandlePreviewKeyDown);
}
}
static void HandlePreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
DoUpdateSource(e.Source);
}
}
static void DoUpdateSource(object source)
{
DependencyProperty property =
GetUpdatePropertySourceWhenEnterPressed(source as DependencyObject);
if (property == null)
{
return;
}
UIElement elt = source as UIElement;
if (elt == null)
{
return;
}
BindingExpression binding = BindingOperations.GetBindingExpression(elt, property);
if (binding != null)
{
binding.UpdateSource();
}
}
}
然后在您的XAML中,您将InputBindingsManager.UpdatePropertySourceWhenEnterPressedProperty
属性设置为您按下Enter键时要更新的属性。 喜欢这个
<TextBox Name="itemNameTextBox"
Text="{Binding Path=ItemName, UpdateSourceTrigger=PropertyChanged}"
b:InputBindingsManager.UpdatePropertySourceWhenEnterPressed="TextBox.Text"/>
(您只需确保在XAML文件的根元素中包含“b”的xmlns clr-名称空间引用,指向您将InputBindingsManager放入哪个名称空间中)。
我不相信有任何“纯粹的XAML”方式来完成你所描述的内容。 您可以设置一个绑定,以便通过设置UpdateSourceTrigger属性来更新每当TextBox中的文本发生更改(而不是在TextBox失去焦点时)的绑定,如下所示:
<TextBox Name="itemNameTextBox"
Text="{Binding Path=ItemName, UpdateSourceTrigger=PropertyChanged}" />
如果您将UpdateSourceTrigger设置为“Explicit”,然后处理TextBox的PreviewKeyDown事件(查找Enter键),那么您可以实现您想要的,但它需要代码隐藏。 也许某种附加属性(类似于我的EnterKeyTraversal属性)woudld适合你。
这就是我解决这个问题的方法。 我创建了一个特殊的事件处理程序,它放在后面的代码中:
private void TextBox_KeyEnterUpdate(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
TextBox tBox = (TextBox)sender;
DependencyProperty prop = TextBox.TextProperty;
BindingExpression binding = BindingOperations.GetBindingExpression(tBox, prop);
if (binding != null) { binding.UpdateSource(); }
}
}
然后我将它作为XAML中的KeyUp事件处理程序添加:
<TextBox Text="{Binding TextValue1}" KeyUp="TextBox_KeyEnterUpdate" />
<TextBox Text="{Binding TextValue2}" KeyUp="TextBox_KeyEnterUpdate" />
事件处理程序使用其sender
引用来使其自己的绑定得到更新。 由于事件处理程序是独立的,因此它应该在复杂的DataTemplate中工作。 现在可以将这一个事件处理程序添加到需要此功能的所有文本框中。