2012-01-05 15 views
7

Breve historia: Un ListBox dentro de un ámbito de enfoque no permite seleccionar un elemento.Usar ListBox dentro del Alcance

largo de la historia:

estoy tratando de hacer un widget contextual para la entrada de datos. Tengo el panel principal con varios campos. Debajo de eso, tengo un panel con FocusManager.FocusScope="True". Este panel se completará con el widget relevante para el campo que actualmente tiene foco. Por ejemplo, seleccionar un campo de fecha mostraría un calendario en la parte inferior de la pantalla.

Tengo varios controles que requieren que el usuario seleccione uno de muchos valores de una lista. Puse un ListBox en el ámbito de enfoque, pero no puedo seleccionar ningún elemento. Cuando se selecciona algo (programáticamente) y hace clic en ListBox, anula la selección de todo.

He probado algunos eventos, y no está recogiendo eventos MouseDown, pero está recogiendo eventos MouseMove. Dispara GotFocus cada vez que hago clic en un elemento, pero nunca dispara LostFocus. No estoy seguro de lo que esto significa, pero espero que pueda ser útil para alguien que está leyendo esto.

Aquí está el código que estoy usando para mostrar el widget contextual. Tengo el siguiente XAML en mi ventana:

<Grid x:Name="EntryWidget" FocusManager.IsFocusScope="True"> 
    <Grid.Resources> 
     <ListBox x:Key="List" ItemsSource="{Binding}" /> 
    </Grid.Resources> 
</Grid> 

utilizo el Window.GotFocus evento enrutado para actualizar el widget con el control apropiado, así:

private void Window_GotFocus(object sender, RoutedEventArgs e) 
{ 
    FrameworkElement focus = (FrameworkElement)FocusManager.GetFocusedElement(this); 
    EntryWidget.Children.Clear(); // Could this be the culprit? 
    object tag = focus.Tag; 
    if (tag != null) 
    { 
     if (EntryWidget.Resources.Contains(tag)) 
     { 
      EntryWidget.Children.Add(EntryWidget.Resources[tag] as UIElement); 
     } 
    } 
} 

Así:

  1. ¿Hay alguna forma de que el ListBox funcione dentro de un ámbito de enfoque?

  2. ¿O hay otro control de lista que funciona mejor dentro de un alcance de enfoque?

  3. ¿O estoy tomando el enfoque equivocado al usar los alcances de enfoque? Mis requisitos: el usuario debe poder seleccionar un elemento de una lista desplazable, que ingresará el valor en el campo actual. El campo actual no debe perder el foco.

+0

No estoy muy seguro de lo que está intentando hacer, pero ha analizado la vinculación de vistas de colecciones, es cuando se selecciona un elemento de una colección, la otra colección se actualiza automáticamente. Aquí hay un enlace de MSDN http://msdn.microsoft.com/en-us/library/system.windows.data.collectionview.aspx – mihajlv

+0

Solo tengo un ListBox. Cuando se selecciona un elemento, debe actualizar el TextBox que tiene el foco. Pero no puedo seleccionar ningún artículo. –

+0

qué tal esto, si tiene un dp de tipo cuadro de texto que se actualiza mediante un cuadro de texto cuando se enfoca, estableciendo el dp igual a él. Luego, cuando haces clic en una lista, actualizas el dp que tiene el cuadro de texto del último elemento que tuvo el foco, sé que es una solución, pero debería funcionar. – mihajlv

Respuesta

1

Cuando hace clic en el ListBox o un elemento que contiene, está configurando el foco del teclado de su aplicación en el ListBox. Esto sucede independientemente de los ámbitos de enfoque que haya definido.

Es posible definir un ámbito de foco para la parte superior del panel (la que contiene los campos), y tienen SelectionChanged conjunto enfoque del cuadro de lista en el panel superior, que realmente va a establecer el foco en el elemento que se centra en ese panel antes de hacer clic en cualquier elemento de ListBox.

<StackPanel> 
    <StackPanel x:Name="upperPanel" FocusManager.IsFocusScope="True" GotFocus="upperPanel_GotFocus"> 
     <TextBox x:Name="TextBox1"></TextBox> 
     <TextBox x:Name="TextBox2"></TextBox> 
    </StackPanel> 
    <StackPanel> 
     <ListBox x:Name="ListBox1" SelectionChanged="ListBox_SelectionChanged"> 
      <ListBoxItem>First</ListBoxItem> 
      <ListBoxItem>Second</ListBoxItem> 
      <ListBoxItem>Third</ListBoxItem> 
     </ListBox> 

     <ListBox x:Name="ListBox2" SelectionChanged="ListBox_SelectionChanged"> 
      <ListBoxItem>4</ListBoxItem> 
      <ListBoxItem>5</ListBoxItem> 
      <ListBoxItem>6</ListBoxItem> 
     </ListBox> 
    </StackPanel> 
</StackPanel> 

private IInputElement focusedElement = null; 

private void upperPanel_GotFocus(object sender, RoutedEventArgs e) 
{ 
    focusedElement = e.Source as IInputElement; 
} 

private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    UpdateTextBoxValue((e.AddedItems[0] as ListBoxItem).Content.ToString()); 
} 

private void UpdateTextBoxValue(string text) 
{ 
    TextBox focusedTextBox = focusedElement as TextBox; 
    if (focusedTextBox != null) 
    { 
     focusedTextBox.Text = text; 
    } 

    upperPanel.Focus(); 
} 

El control activo actualmente en el ámbito upperPanel se mantiene hasta a la fecha por el manejador GotFocus evento, y el método UpdateTextBoxValue es el encargado de establecer el texto en la TextBox control activo y ajustar el foco de nuevo a eso.

Supongo que está familiarizado con los términos que estaba usando (enfoque del teclado/enfoque lógico); si no, puede echar un vistazo al Focus Overview o puede simplemente preguntar.

+0

Hmm, suena hackish. Tengo varios controles además del ListBox que pueden mostrarse para otros campos. Si tengo que hacer eso GetFocusedElement para cada control que quiero mostrar, ¿hay alguna manera mejor? Mencionaste que está configurando el foco del teclado en el ListBox. Si ese es el caso, ¿por qué presionar un tipo de tecla en el campo en el ámbito de enfoque principal? El ListBox no parece tener el foco del teclado. –

+0

@kendfrey He editado mi respuesta. Si te estás refiriendo a mi ejemplo, presionar una tecla escribe texto en el cuadro de texto porque estoy configurando el foco del teclado desde el código. –

+0

¿Su campo 'focusedElement' no derrota el propósito de un alcance de enfoque? Y no me refiero a tu código. Mi código no me permite (teclado) centrarse en el ListBox. Publicaré el código que creo que podría ser relevante. –

2

Mi respuesta sería No use el alcance para esto.

Estás derrotando el propósito del enfoque. ¿Qué pasa si alguien no puede usar el mouse y quiere usar el teclado en su lugar?

¿por qué no tener la selección en la lista y luego volver a establecer el foco en el control original, en lugar de hacer todo este trabajo adicional con los ámbitos de enfoque?

+0

Buena idea. Esta aplicación está diseñada para una Tablet PC, por lo tanto, la compatibilidad con el teclado no es una prioridad. ¿Pero no son los ámbitos de enfoque diseñados para una situación como esta? Sería mucho trabajo implementar su propio sistema de enfoque, ¿no? –

+0

, pero si se trata de un sistema de tableta, con solo toque, ¿para qué sirve el enfoque? Si no lo está usando para * foco del teclado *, entonces no estoy seguro para qué lo está usando. –

+0

Podemos permitir que el usuario escriba directamente. Si no utilizara el enfoque para hacer un seguimiento del campo actual, ¿qué usaría entonces? Las claves de enfoque, como un cuadro de texto resaltado, son útiles, y sería contrario a la intuición mostrar el foco en algún otro control que no sea el campo actual. Y por favor no me juzguen por intentar ingresar datos en una tableta. :) :( –

Cuestiones relacionadas