.net - guia - No hay ListBox.SelectionMode="None", ¿hay alguna otra forma de deshabilitar la selección en un listbox?
qgis manual (15)
Enfoque 1 - ItemsControl
A menos que necesite otros aspectos de ListBox
, podría usar ItemsControl
en ItemsControl
lugar. Coloca elementos en el ItemsPanel
y no tiene el concepto de selección.
<ItemsControl ItemsSource="{Binding MyItems}" />
De forma predeterminada, ItemsControl
no admite la virtualización de sus elementos secundarios. Si tiene muchos elementos, la virtualización puede reducir el uso de la memoria y mejorar el rendimiento, en cuyo caso podría usar el método 2 y dar estilo al ListBox
, o agregar virtualización a su ItemsControl
.
Enfoque 2 - Estilo ListBox
Alternativamente, simplemente aplique estilo al ListBox de manera que la selección no sea visible.
<ListBox.Resources>
<Style TargetType="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>
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
</Style>
</ListBox.Resources>
¿Cómo desactivo la selección en un ListBox?
Aquí hay respuestas bastante buenas, pero estaba buscando algo ligeramente diferente: quiero una 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 otra cosa: utilicé un nuevo estilo para mi listbox, que redefine por completo las plantillas:
<Style x:Key="PlainListBoxStyle" TargetType="ListBox">
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}">
<ItemsPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Comenzando con eso, puede agregar fácilmente su propio resaltado de selección, o dejarlo así si no quiere ninguno.
Encontré una solución muy simple y directa que funcionaba para mí, espero que también te sirva a ti
<ListBox ItemsSource="{Items}">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Focusable" Value="False"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
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:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsHitTestVisible" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
IsEnabled = falso
La respuesta de Hallgeir Engen es una buena solución, pero el problema es que después de la publicación posterior, todos los elementos se vuelven seleccionables nuevamente, por lo que se requiere que en Page_Load se agregue a cada elemento ListItem el atributo disabled.
Pero hay una solución aún más simple.
En lugar de deshabilitar todos los ListItems, puede desactivar el ListBox una sola vez , y todos sus elementos de lista también se desactivan. establezca Enabled en false, no deshabilita ListBox en absoluto , pero si agrega la siguiente línea en Page_Load :
this.listbox.Attributes.Add("disabled", "disabled");
Después de la publicación posterior, los elementos no se pueden seleccionar, por lo que puede poner esta línea de código en:
if (!this.IsPostBack)
{
}
Pero todos los elementos siguen siendo superposición gris, por lo que si desea colorear todos los elementos, realice la clase css:
.ListItemColor option
{
color: Black; /*(default color for list item, if it is not disabled)*/
}
A continuación, establezca CssClass del ListBox en esta clase css arriba. Si desea colorear algunos elementos de la lista (pero no todos), tendrá que darle un estilo a algunos elementos y darle a cada uno su color a través de la fuente (marcado) o el código (javascript, c # o Visual Basic).
Mientras que la respuesta de @Drew Noakes es una solución rápida para la mayoría de los casos, hay un pequeño error al configurar x: pinceles estáticos.
Cuando establece x: pinceles estáticos 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 tiene un ComboBox dentro de su ListBoxItem, deshabilitará el mouse sobre el resaltado dentro del ComboBox.
En su lugar, considere establecer los VisualStates para los eventos Selected, Unselected y MouseOver como se tratan en la solución mencionada en este subproceso de : Eliminar el control resaltado de ListBoxItem pero no los controles secundarios .
-Frinny
Otra opción que vale la pena considerar es la desactivación de ListBoxItems. Esto puede hacerse configurando ItemContainerStyle como se muestra en el siguiente fragmento.
<ListBox ItemsSource="{Binding YourCollection}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsEnabled" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Si no desea que el texto sea gris, puede especificar el color desactivado 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.
Para desactivar 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.
ListItem item = new ListItem(yourvalue, yourkey);
item.Attributes.Add("disabled","disabled");
lb1.Items.Add(item);
Para mí, la mejor solución es:
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Focusable" Value="True"/>
<Setter Property="IsHitTestVisible" Value="False" />
</Style>
</ListBox.ItemContainerStyle>
Puede cambiar a usar un ItemsControl
lugar de un ListBox
. Un ItemsControl
no tiene ningún concepto de selección, por lo que no hay nada que desactivar.
Puede colocar un Textblock encima de su listbox, no cambiará el aspecto de su aplicación y tampoco le permitirá seleccionar ningún elemento.
Tal vez necesita una sola funcionalidad de ItemsControl? No permite la selección:
<ItemsControl ItemsSource="{Binding Prop1}" ItemTemplate="{StaticResource DataItemsTemplate}" />
Una solución simple que funciona en Windows Phone, por ejemplo, está en la configuración de la selección del elemento seleccionado como nulo:
<ListBox SelectionChanged="ListBox_SelectionChanged">
Y en el código detrás:
private void ListBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
(sender as ListBox).SelectedItem = null;
}
Nota: Esta solución no deshabilita la selección mediante la navegación por el teclado o haciendo clic con el botón derecho (es decir, las teclas de flecha seguidas de la tecla de espacio).
Todas las respuestas anteriores eliminan la capacidad de seleccionar completamente (sin cambio en el 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 la entrada del usuario? ¿Puede ser que desee "congelar" la selección del usuario sin desactivar todo Listbox?
La solución es envolver todo ElementsContentTemplate en un botón que no tenga visual chrome. El tamaño del botón debe ser igual al tamaño del artículo, por lo que está completamente cubierto. Ahora usa la propiedad IsEnabled 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 lleguen al ListboxItem-Eventhandler. Your ItemsDataTemplate seguirá recibiendo MouseEvents porque es parte del contenido de los botones.
Desactive el botón para permitir cambiar la selección haciendo clic.
<Style x:Key="LedCT" TargetType="{x:Type ListBoxItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Button IsEnabled="{Binding IsSelectable, Converter={StaticResource BoolOppositeConverter}}" Template="{DynamicResource InvisibleButton}">
<ContentPresenter />
</Button>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="InvisibleButton" TargetType="{x:Type Button}">
<ContentPresenter/>
</ControlTemplate>
dartrax