¿Puede un ListBox de WPF ser "solo lectura"?
-
03-07-2019 - |
Pregunta
Tenemos un escenario en el que queremos mostrar una lista de elementos e indicar cuál es el " actual " elemento (con un pequeño marcador de flecha o un color de fondo cambiado).
ItemsControl no nos sirve, porque necesitamos el contexto de " SelectedItem " ;. Sin embargo, queremos mover la selección de manera programática y no permitir que el usuario la cambie.
¿Existe una forma sencilla de hacer que un ListBox no sea interactivo? Podemos manipularlo deliberadamente tragando los eventos del mouse y el teclado, pero ¿me falta alguna propiedad fundamental (como configurar " IsEnabled " falsa sin afectar su estilo visual) que nos da lo que queremos?
O ... ¿hay otro control WPF que sea el mejor de los dos mundos: un ItemsControl con una propiedad SelectedItem?
Solución
Una opción es establecer ListBoxItem.IsEnabled
en false
:
<ListBox x:Name="_listBox">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsEnabled" Value="False"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Esto garantiza que los elementos no se puedan seleccionar, pero que no se muestren como desee. Para solucionar esto, puedes jugar con disparadores y / o plantillas. Por ejemplo:
<ListBox x:Name="_listBox">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsEnabled" Value="False"/>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Otros consejos
Tuve el mismo problema. Lo resolví dejando el conjunto de IsEnabled en verdadero y manejando el evento PreviewMouseDown del ListBox. En el controlador, establezca e.Handled a true en el caso de que no quiera editarlo.
private void lstSMTs_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
e.Handled = !editRights;
}
¿Es su base de datos ItemsControl / ListBox?
Solo estoy pensando que podrías hacer que el Pincel de fondo de cada elemento esté vinculado a una propiedad de los datos de origen, o pasar la propiedad a través de un convertidor. Algo como:
<ItemsControl DataContext="{Binding Source={StaticResource Things}}" ItemsSource="{Binding}" Margin="0">
<ItemsControl.Resources>
<local:SelectedConverter x:Key="conv"/>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<local:Control Background="{Binding Path=IsSelected, Converter={StaticResource conv}}"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
Funcionalidad ListBoxItem no seleccionable (o ListViewItem) usando propiedades adjuntas: http: // thrash505. wordpress.com/2011/01/04/non-selectable-listboxitem-or-listviewitem-using-attached-properties/