¿Podría proporcionar un ejemplo en el que sea válido tener un ListBox que no puede seleccionar? Dado que el comportamiento principal es seleccionar elementos. Probablemente elegiría otra forma de mostrarlo. (Este no soy yo tratando de ser un crítico, sino más bien un interés genuino sobre dónde podría ocurrir esto)
Marthin
3
@ Martin: por ejemplo, si desea arrastrar contenido desde un elemento de cuadro de lista; en este caso, probablemente no esté interesado en seleccionar ese elemento. TAMBIÉN: al arrastrar un elemento: el elemento seleccionado del cuadro de lista cambia mientras lo arrastra dentro del cuadro de lista; consulte esta publicación stackoverflow.com/questions/7589142/…
Danield
1
Creo que la razón por la que Shimmy quiere usar ListBox es que el autor de la pregunta puede hacer que el cuadro de lista sea seleccionable en algún momento. La pregunta también es valiosa para mí. Digamos que estás construyendo un juego de naipes. Puede seleccionar una tarjeta de sus tarjetas, a veces, puede seleccionar varias y en otras ocasiones, no puede seleccionar ninguna.
Gqqnbig
1
Además, a veces tienes 10 cartas y solo 4 de ellas son seleccionables. Entre los 4, puede seleccionar hasta 3.
Gqqnbig
1
@Marthin: cuando tienes un GridView en un ListBox. Los encabezados de Gridview proporcionan mucha funcionalidad que no está disponible en otros lugares. Y tiene controles de edición en las celdas de la vista de cuadrícula.
Robin Davies
Respuestas:
264
Enfoque 1 - ItemsControl
A menos que necesite otros aspectos de la ListBox, podría utilizar ItemsControlen su lugar. Coloca elementos en ItemsPanely no tiene el concepto de selección.
<ItemsControlItemsSource="{Binding MyItems}"/>
Por defecto, ItemsControlno admite la virtualización de sus elementos secundarios. Si tiene muchos elementos, la virtualización puede reducir el uso de memoria y mejorar el rendimiento, en cuyo caso podría usar el enfoque 2 y darle estilo ListBox, o agregar virtualización a suItemsControl .
Enfoque 2 - Estilo ListBox
Alternativamente, simplemente diseñe el ListBox de modo que la selección no sea visible.
<ListBox.Resources><StyleTargetType="ListBoxItem"><Style.Resources><!-- SelectedItem with focus --><SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}"
Color="Transparent"/><!-- SelectedItem without focus --><SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}"
Color="Transparent"/><!-- SelectedItem text foreground --><SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}"
Color="Black"/></Style.Resources><SetterProperty="FocusVisualStyle"Value="{x:Null}"/></Style></ListBox.Resources>
no, sólo cambiará el efecto visual, no el comportamiento de la selección real
Thomas Levesque
8
Mi primera sugerencia fue usar ItemsControl. ¿Te perdiste eso? :)
Drew Noakes
55
Volviendo a leer estos comentarios nuevamente, quiero señalar que el comentario de @Thomas Levesque solo es cierto sobre el segundo enfoque que muestro. El uso de plain ItemsControleliminará por completo cualquier concepto de selección.
Drew Noakes
1
La solución ItemsControl elimina el soporte de desplazamiento de la caja (barra de desplazamiento y rueda del mouse).
MuiBienCarlota
1
+1 para el Enfoque 1 - ItemsControl. Si tenemos una página enorme que tenemos que desplazar, si el usuario pasa el mouse sobre un ListBox, deshabilita efectivamente la MouseWheel cuando el cuadro de lista toma los eventos de MouseWheel. Esto significa que el usuario se siente frustrado de que la rueda del mouse utilizada para desplazarse por toda la página deje de funcionar aleatoriamente, dependiendo de si el mouse está sobre un cuadro de lista o no.
Contango
159
Encontré una solución muy simple y directa que funciona para mí, espero que también sirva para ti
Esto es perfecto. evita que el elemento seleccionado y otros controles como botones sigan funcionando. exactamente lo que estaba buscando
Franck
1
+1 para este enfoque. Si tenemos una página enorme que tenemos que desplazar, si el usuario pasa el mouse sobre un ListBox, deshabilita efectivamente la MouseWheel cuando el cuadro de lista toma los eventos de MouseWheel. Esto significa que el usuario se siente frustrado de que la rueda del mouse utilizada para desplazarse por toda la página deje de funcionar aleatoriamente, dependiendo de si el mouse está sobre un cuadro de lista o no.
Contango
Excelente. Un enfoque similar también funcionó para mí cuando necesitaba botones en los elementos para no causar la selección del elemento, pero solo si se hizo clic en otra área del elemento. ¡Simplemente configure los botones Focusable = "False"!
Jony Adamit
1
Agregue esta propiedad adicional para eliminar también el resaltado del mouseover: <Setter Property="IsHitTestVisible" Value="False" />
DonBoitnott
25
Puede cambiar a usar un en ItemsControllugar de un ListBox. Un ItemsControlno tiene un concepto de selección, por lo que no hay nada que apagar.
Encantador. Nunca supe que podía declarar directamente ItemsControl, pensé que era virtual (debe anular), ¡gracias!
Shimmy Weitzhandler
¿Pero ItemsControl todavía representaría mis artículos en una línea?
Chry Cheng el
@Chry sí lo haría, y además, siempre puedes configurarlo manualmente ItemTemplate.
Shimmy Weitzhandler
2
Esto termina perdiendo demasiada funcionalidad, por ejemplo, desplazamiento.
Jeff
@Jeff puedes envolver el ItemsControl en un ScrollViewer para ganar desplazamiento.
Wilka
12
Otra opción que vale la pena considerar es deshabilitar ListBoxItems. Esto se puede hacer configurando el ItemContainerStyle como se muestra en el siguiente fragmento.
Si no desea que el texto sea gris, puede especificar el color deshabilitado agregando un pincel a los recursos del estilo con la siguiente clave: {x: Static SystemColors.GrayTextBrushKey}. La otra solución sería anular la plantilla de control ListBoxItem.
Simple y funcional, gracias! Y también es aplicable en WP 8.1 Runtime.
Malutek
8
Esto también funcionará, si tengo la necesidad de usar listbox en lugar de itemscontrol, pero solo estoy mostrando los elementos que no deberían ser seleccionables, uso:
Muy buenas respuestas aquí, pero estaba buscando algo ligeramente diferente: quiero selección, pero simplemente no quiero que se muestre (o se muestre en un asunto diferente).
Las soluciones anteriores no me funcionaron (completamente), así que hice algo más: utilicé un nuevo estilo para mi cuadro de lista, que redefine completamente las plantillas:
Si bien la respuesta de @Drew Noakes es una solución rápida para la mayoría de los casos, hay un pequeño defecto que viene con la configuración de x: cepillos estáticos.
Cuando configura los pinceles x: Static como se sugiere, todos los controles secundarios dentro del elemento del cuadro de lista heredarán este estilo.
Eso significa que, si bien esto funcionará para deshabilitar el resaltado del elemento del cuadro de lista, puede provocar efectos no deseados para los controles secundarios.
Por ejemplo, si tuviera un ComboBox dentro de su ListBoxItem, deshabilitaría el mouse sobre el resaltado dentro del ComboBox.
En mi caso, no quiero deshabilitar la interacción del usuario con el contenido de mi, ListBoxItemspor lo que la solución para configurar IsEnabledno funcionará para mí.
La otra solución que intenta cambiar el estilo ListBoxItemanulando las propiedades relacionadas con el color solo funciona para aquellas instancias en las que está seguro de que la plantilla usa esas propiedades. Eso está bien para los estilos predeterminados, pero rompe con los estilos personalizados.
Las soluciones que usan un sistema ItemsControlrompen demasiadas cosas, ya que ItemsControltienen un aspecto completamente diferente al estándar ListBoxy no admiten la virtualización, lo que significa que de ItemsPaneltodos modos tiene que volver a crear la plantilla .
Lo anterior no cambia el aspecto predeterminado del ListBox, no deshabilita los elementos en las plantillas de datos para ListBox, admite la virtualización de forma predeterminada y funciona independientemente de los estilos que pueden o no estar en uso en su aplicación. Es el principio KISS.
Nota: Esta solución no deshabilita la selección mediante la navegación con el teclado o haciendo clic derecho (es decir, las teclas de flecha seguidas de la barra espaciadora)
Todas las respuestas anteriores eliminan la selección de habilidad por completo (sin cambiar en tiempo de ejecución) o simplemente eliminan el efecto visual, pero no la selección.
Pero, ¿qué sucede si desea poder seleccionar y mostrar la selección por código, pero no por entrada del usuario? ¿Es posible que desee "congelar" la selección del usuario sin deshabilitar todo el cuadro de lista?
La solución es envolver todo el ItemContentTemplate en un botón que no tiene cromo visual. El tamaño del botón debe ser igual al tamaño del artículo, por lo que está completamente cubierto. Ahora use la propiedad IsEnabled-button del botón:
Habilite el botón para "congelar" el estado de selección del elemento. Esto funciona porque el botón habilitado come todos los eventos del mouse antes de que aparezcan en el ListboxItem-Eventhandler. Your ItemsDataTemplate seguirá recibiendo MouseEvents porque es parte del contenido de los botones.
Deshabilite el botón para permitir cambiar la selección haciendo clic.
@Shimmy: Es común que las respuestas triviales sean similares. Aquí no hay duplicación digna de ninguna bandera. Si tiene más preguntas al respecto, consulte Meta Stack Overflow .
0
Puede colocar un bloque de texto sobre su cuadro de lista, no cambiará el aspecto de su aplicación y tampoco permitirá seleccionar ningún elemento.
Encontré una manera perfecta.
Establezca ListBox IsHitTestVisible en false para que el usuario no pueda desplazar el mouse o desplazarse hacia abajo o hacia arriba.
Capture PreviewGotKeyboardFocus e.Handled = true para que el usuario pueda seleccionar el elemento con el teclado Tab, Flecha arriba, Flecha abajo.
De esta manera ventaja:
Los elementos de ListBox en primer plano no se volverán grises.
ListBox Background puede establecerse en Transparent
Para deshabilitar una o más opciones en su cuadro de lista / menú desplegable, puede agregar el atributo "deshabilitado" como se muestra a continuación. Esto evita que el usuario seleccione esta opción y obtiene una superposición gris.
Respuestas:
Enfoque 1 -
ItemsControl
A menos que necesite otros aspectos de la
ListBox
, podría utilizarItemsControl
en su lugar. Coloca elementos enItemsPanel
y no tiene el concepto de selección.Por defecto,
ItemsControl
no admite la virtualización de sus elementos secundarios. Si tiene muchos elementos, la virtualización puede reducir el uso de memoria y mejorar el rendimiento, en cuyo caso podría usar el enfoque 2 y darle estiloListBox
, o agregar virtualización a suItemsControl
.Enfoque 2 - Estilo
ListBox
Alternativamente, simplemente diseñe el ListBox de modo que la selección no sea visible.
fuente
ItemsControl
eliminará por completo cualquier concepto de selección.Encontré una solución muy simple y directa que funciona para mí, espero que también sirva para ti
fuente
Focusable = "False"
!<Setter Property="IsHitTestVisible" Value="False" />
Puede cambiar a usar un en
ItemsControl
lugar de unListBox
. UnItemsControl
no tiene un concepto de selección, por lo que no hay nada que apagar.fuente
ItemTemplate
.Otra opción que vale la pena considerar es deshabilitar ListBoxItems. Esto se puede hacer configurando el ItemContainerStyle como se muestra en el siguiente fragmento.
Si no desea que el texto sea gris, puede especificar el color deshabilitado agregando un pincel a los recursos del estilo con la siguiente clave: {x: Static SystemColors.GrayTextBrushKey}. La otra solución sería anular la plantilla de control ListBoxItem.
fuente
Esto también funcionará, si tengo la necesidad de usar listbox en lugar de itemscontrol, pero solo estoy mostrando los elementos que no deberían ser seleccionables, uso:
fuente
Muy buenas respuestas aquí, pero estaba buscando algo ligeramente diferente: quiero selección, pero simplemente no quiero que se muestre (o se muestre en un asunto diferente).
Las soluciones anteriores no me funcionaron (completamente), así que hice algo más: utilicé un nuevo estilo para mi cuadro de lista, que redefine completamente las plantillas:
Comenzando con eso, puede agregar fácilmente su propio resaltado de selección, o dejarlo así si no desea ninguno.
fuente
Si bien la respuesta de @Drew Noakes es una solución rápida para la mayoría de los casos, hay un pequeño defecto que viene con la configuración de x: cepillos estáticos.
Cuando configura los pinceles x: Static como se sugiere, todos los controles secundarios dentro del elemento del cuadro de lista heredarán este estilo.
Eso significa que, si bien esto funcionará para deshabilitar el resaltado del elemento del cuadro de lista, puede provocar efectos no deseados para los controles secundarios.
Por ejemplo, si tuviera un ComboBox dentro de su ListBoxItem, deshabilitaría el mouse sobre el resaltado dentro del ComboBox.
En su lugar, considere configurar VisualStates para los eventos Selected, Unselected y MouseOver como se cubre en la solución mencionada en este hilo de stackoverflow: Eliminar Control Highlight From ListBoxItem pero no los controles secundarios .
-Frinny
fuente
Propongo otra solución más. Simplemente cambie la plantilla
ListBoxItem
para que no sea más que unContentPresenter
, así ...Mis razones para este enfoque son las siguientes:
En mi caso, no quiero deshabilitar la interacción del usuario con el contenido de mi,
ListBoxItems
por lo que la solución para configurarIsEnabled
no funcionará para mí.La otra solución que intenta cambiar el estilo
ListBoxItem
anulando las propiedades relacionadas con el color solo funciona para aquellas instancias en las que está seguro de que la plantilla usa esas propiedades. Eso está bien para los estilos predeterminados, pero rompe con los estilos personalizados.Las soluciones que usan un sistema
ItemsControl
rompen demasiadas cosas, ya queItemsControl
tienen un aspecto completamente diferente al estándarListBox
y no admiten la virtualización, lo que significa que deItemsPanel
todos modos tiene que volver a crear la plantilla .Lo anterior no cambia el aspecto predeterminado del
ListBox
, no deshabilita los elementos en las plantillas de datos paraListBox
, admite la virtualización de forma predeterminada y funciona independientemente de los estilos que pueden o no estar en uso en su aplicación. Es el principio KISS.fuente
Nota: Esta solución no deshabilita la selección mediante la navegación con el teclado o haciendo clic derecho (es decir, las teclas de flecha seguidas de la barra espaciadora)
Todas las respuestas anteriores eliminan la selección de habilidad por completo (sin cambiar en tiempo de ejecución) o simplemente eliminan el efecto visual, pero no la selección.
Pero, ¿qué sucede si desea poder seleccionar y mostrar la selección por código, pero no por entrada del usuario? ¿Es posible que desee "congelar" la selección del usuario sin deshabilitar todo el cuadro de lista?
La solución es envolver todo el ItemContentTemplate en un botón que no tiene cromo visual. El tamaño del botón debe ser igual al tamaño del artículo, por lo que está completamente cubierto. Ahora use la propiedad IsEnabled-button del botón:
Habilite el botón para "congelar" el estado de selección del elemento. Esto funciona porque el botón habilitado come todos los eventos del mouse antes de que aparezcan en el ListboxItem-Eventhandler. Your ItemsDataTemplate seguirá recibiendo MouseEvents porque es parte del contenido de los botones.
Deshabilite el botón para permitir cambiar la selección haciendo clic.
Dartrax
fuente
¿Tal vez solo necesita la funcionalidad de ItemsControl? No permite la selección:
fuente
Puede colocar un bloque de texto sobre su cuadro de lista, no cambiará el aspecto de su aplicación y tampoco permitirá seleccionar ningún elemento.
fuente
Una solución simple que funciona en Windows Phone, por ejemplo, es la selección que establece el elemento seleccionado en nulo:
Y en el código detrás:
fuente
Encontré una manera perfecta.
Establezca ListBox IsHitTestVisible en false para que el usuario no pueda desplazar el mouse o desplazarse hacia abajo o hacia arriba.
Capture PreviewGotKeyboardFocus e.Handled = true para que el usuario pueda seleccionar el elemento con el teclado Tab, Flecha arriba, Flecha abajo.
De esta manera ventaja:
xmal
código
fuente
Para mí la mejor solución es:
fuente
IsEnabled = falso
fuente
Para deshabilitar una o más opciones en su cuadro de lista / menú desplegable, puede agregar el atributo "deshabilitado" como se muestra a continuación. Esto evita que el usuario seleccione esta opción y obtiene una superposición gris.
fuente