"Cuando agrego este disparador se selecciona el elemento cuando el foco está en un cuadro de texto niño, pero el primer comportamiento desaparece. Ahora al hacer clic fuera del cuadro de lista, el artículo es seleccionada de".
En realidad, no creo que haya perdido ese comportamiento original. Lo que sospecho que está sucediendo es que está haciendo clic directamente en el cuadro de texto desde otro lugar, por lo que el ListBoxItem subyacente nunca se seleccionó realmente. Sin embargo, si lo hiciera, verías que la selección permanecerá después de que te hayas ido como quieras.
Puede probar esto forzando que ListBoxItem se seleccione haciendo clic directamente en él (nota al margen: siempre debe darle un fondo, incluso si es 'transparente' para que pueda recibir clics del mouse, que ganó ' t si es nulo) o simplemente presionando 'Shift-Tab' para establecer el foco allí, de regreso del cuadro de texto.
Sin embargo, eso no resuelve su problema, que es que TextBox obtiene el foco pero no permite que el elemento ListBoxItem subyacente lo sepa.
Los dos enfoques que puede usar para eso son un activador de evento o un comportamiento adjunto.
El primero es un desencadenante de evento en el evento IsKeyboardFocusWithinChanged donde establece 'IsSelected' en verdadero si el foco del teclado cambió a verdadero. (Nota: la respuesta de Sheridan hace una notificación falsa de cambio pero no debe usarse en los casos en que puede seleccionar varias veces en la lista porque todo se selecciona). Pero incluso un desencadenante de evento causa problemas porque pierde los comportamientos de selección múltiple como alternar o hacer clic en rango, etc.
El otro (y mi enfoque preferido) es escribir un comportamiento adjunto que establezca en ListBoxItem, ya sea directamente o mediante un estilo si lo prefiere.
Aquí está el comportamiento adjunto. Nota: De nuevo tendrá que manejar las cosas de selección múltiple si desea implementar eso. También tenga en cuenta que, aunque estoy adjuntando el comportamiento a un ListBoxItem, dentro de Ihe echo a UIElement. De esta forma también puede usarlo en ComboBoxItem, TreeViewItem, etc. Básicamente cualquier ContainerItem en un control basado en Selector.
public class AutoSelectWhenAnyChildGetsFocus
{
public static readonly DependencyProperty EnabledProperty = DependencyProperty.RegisterAttached(
"Enabled",
typeof(bool),
typeof(AutoSelectWhenAnyChildGetsFocus),
new UIPropertyMetadata(false, Enabled_Changed));
public static bool GetEnabled(DependencyObject obj){ return (bool)obj.GetValue(EnabledProperty); }
public static void SetEnabled(DependencyObject obj, bool value){ obj.SetValue(EnabledProperty, value); }
private static void Enabled_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var attachEvents = (bool)e.NewValue;
var targetUiElement = (UIElement)sender;
if(attachEvents)
targetUiElement.IsKeyboardFocusWithinChanged += TargetUiElement_IsKeyboardFocusWithinChanged;
else
targetUiElement.IsKeyboardFocusWithinChanged -= TargetUiElement_IsKeyboardFocusWithinChanged;
}
static void TargetUiElement_IsKeyboardFocusWithinChanged(object sender, DependencyPropertyChangedEventArgs e)
{
var targetUiElement = (UIElement)sender;
if(targetUiElement.IsKeyboardFocusWithin)
Selector.SetIsSelected(targetUiElement, true);
}
}
... y sólo tiene que añadir esto como un regulador de la propiedad en el estilo de su ListBoxItem
<Setter Property="behaviors:AutoSelectWhenAnyChildGetsFocus.Enabled" Value="True" />
supuesto, esto supone que haya importado un espacio de nombres XML llamado 'comportamientos' que apunta al espacio de nombres donde está contenida la clase Puedes poner la clase en una biblioteca compartida 'Helper', que es lo que hacemos. De esta forma, en cualquier lugar que lo deseemos, es una propiedad simple establecida en el XAML y el comportamiento se ocupa de todo lo demás.
Hermosa solución solo XAML: https://stackoverflow.com/a/15383435/419761 – l33t