Puede crear un enfoque XAML puro creando un comportamiento adjunto .
Algo como esto:
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();
}
}
}
Luego, en su XAML, establece la InputBindingsManager.UpdatePropertySourceWhenEnterPressedProperty
propiedad en la que desea actualizar cuando Enterse presiona la tecla. Me gusta esto
<TextBox Name="itemNameTextBox"
Text="{Binding Path=ItemName, UpdateSourceTrigger=PropertyChanged}"
b:InputBindingsManager.UpdatePropertySourceWhenEnterPressed="TextBox.Text"/>
(Solo debe asegurarse de incluir una referencia xmlns clr-namespace para "b" en el elemento raíz de su archivo XAML que apunte al espacio de nombres en el que colocó InputBindingsManager).
UpdatePropertySourceWhenEnterPressed
cambia de un valor válido a un valor válido diferente, se cancela la suscripción y se vuelve a suscribir alPreviewKeyDown
evento innecesariamente. En cambio, todo lo que debe necesitar es verificar si loe.NewValue
esnull
o no. Si no es asínull
, suscríbete; de lo contrario, sinull
, anule la suscripción.Así es como resolví este problema. Creé un controlador de eventos especial que entró en el código detrás:
Luego, acabo de agregar esto como un controlador de eventos KeyUp en el XAML:
El controlador de eventos usa su
sender
referencia para hacer que su propio enlace se actualice. Dado que el controlador de eventos es autónomo, debería funcionar en un DataTemplate complejo. Este controlador de eventos ahora se puede agregar a todos los cuadros de texto que necesitan esta función.fuente
KeyBinding
en el XAML para disparar este método porque mi interfaz de usuario tiene un control de "defecto" que llama la tecla enter. Debe capturarlo dentro de este TextBox para evitar que se propague por el árbol de la interfaz de usuario hasta el control "Predeterminado".No creo que haya ninguna forma "XAML puro" de hacer lo que estás describiendo. Puede configurar un enlace para que se actualice cada vez que cambia el texto en un TextBox (en lugar de cuando el TextBox pierde el foco) estableciendo la propiedad UpdateSourceTrigger , así:
Si configura UpdateSourceTrigger en "Explicit" y luego maneja el evento PreviewKeyDown de TextBox (buscando la tecla Enter), entonces podría lograr lo que desea, pero requeriría código subyacente. Tal vez algún tipo de propiedad adjunta (similar a mi EnterKeyTraversal propiedad) woudld trabajo para usted.
fuente
Puede crear fácilmente su propio control heredando de TextBox y reutilizarlo en todo su proyecto.
Algo similar a esto debería funcionar:
Puede haber una forma de evitar este paso, pero de lo contrario, debería enlazar así (usando Explicit):
fuente
Si combina las soluciones de Ben y ausadmin, obtendrá una solución muy compatible con MVVM:
... lo que significa que está pasando el
TextBox
propio como parámetro alCommand
.Esto hace que se
Command
vea así (si está utilizando unaDelegateCommand
implementación de estilo en su VM):Esta
Command
implementación se puede usar para cualquierTextBox
y, lo mejor de todo, sin código en el código subyacente, aunque es posible que desee ponerlo en su propia clase para que no haya dependenciasSystem.Windows.Controls
en su VM. Depende de cuán estrictas sean las pautas de su código.fuente
Aquí hay un enfoque que me parece bastante sencillo y más fácil que agregar un AttachedBehaviour (que también es una solución válida). Usamos el UpdateSourceTrigger predeterminado (LostFocus para TextBox), y luego agregamos un InputBinding a la tecla Enter, vinculado a un comando.
El xaml es el siguiente
Entonces los métodos de comando son
Y el TextBox está vinculado a la propiedad
Hasta ahora, esto parece funcionar bien y detecta el evento Enter Key en TextBox.
fuente
Esta no es una respuesta a la pregunta original, sino más bien una extensión de la respuesta aceptada por @Samuel Jack. Hice lo siguiente en mi propia aplicación y me asombró la elegancia de la solución de Samuel. Es muy limpio y muy reutilizable, ya que se puede usar en cualquier control, no solo en el
TextBox
. Pensé que esto debería compartirse con la comunidad.Si tiene una ventana con mil y
TextBoxes
todas requieren actualizar la fuente de enlace en Enter, puede adjuntar este comportamiento a todas ellas al incluir el XAML a continuación en su enWindow
Resources
lugar de adjuntarlo a cada TextBox. Primero debe implementar el comportamiento adjunto según la publicación de Samuel , por supuesto.Siempre puede limitar el alcance, si es necesario, colocando el Estilo en los Recursos de uno de los elementos secundarios de la Ventana (es decir, a
Grid
) que contiene los TextBoxes de destino.fuente
En caso de que esté usando MultiBinding con su TextBox, debe usar el
BindingOperations.GetMultiBindingExpression
método en lugar deBindingOperations.GetBindingExpression
.fuente
Esto funciona para mi:
fuente
Respondido aquí con bastante elegancia usando comportamientos adjuntos, mi método preferido para casi cualquier cosa.
WPF cómo hacer que el cuadro de texto pierda el foco después de presionar enter
fuente
Personalmente, creo que tener una extensión de marcado es un enfoque más limpio.
fuente
Una solución diferente (creo que no usa xaml pero todavía bastante limpia).
fuente