template wpf listview

template - WPF ListView desactiva la selección



wpf listview grouping (10)

Además de la solución anterior ... usaría un MultiTrigger para permitir que los resaltados MouseOver continúen funcionando después de la selección, de modo que el estilo de su ListViewItem sea:

<ListView.ItemContainerStyle> <Style TargetType="ListViewItem"> <Style.Triggers> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsSelected" Value="True" /> <Condition Property="IsMouseOver" Value="False" /> </MultiTrigger.Conditions> <MultiTrigger.Setters> <Setter Property="Background" Value="{x:Null}" /> <Setter Property="BorderBrush" Value="{x:Null}" /> </MultiTrigger.Setters> </MultiTrigger> </Style.Triggers> </Style> </ListView.ItemContainerStyle>

Tengo un simple ListView de WPF y una simple pregunta:

¿Es posible desactivar la selección, por lo que cuando el usuario hace clic en la fila, la fila no se resalta?

Me gustaría que la fila 1 se vea como la fila 0 cuando se hace clic.

Posiblemente relacionado: ¿puedo darle estilo al aspecto de la opción de desplazamiento / selección? P.ej. para reemplazar el aspecto de desplazamiento del gradiente azul (línea 3) con un color sólido personalizado. He encontrado this y this , desafortunadamente no ayuda.

(Lograr lo mismo sin usar ListView también es aceptable. Me gustaría poder usar el desplazamiento lógico y la virtualización de UI como lo hace ListView)

El XAML para ListView es:

<ListView Height="280" Name="listView"> <ListView.Resources> <!-- attempt to override selection color --> <SolidColorBrush x:Key="{x:Static SystemColors.HighlightColorKey}" Color="Green" /> </ListView.Resources> <ListView.View> <GridView> <GridView.Columns> <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" /> <!-- more columns --> </GridView.Columns> </GridView> </ListView.View> </ListView>


Aquí está la plantilla predeterminada para ListViewItem de Blend:

Plantilla predeterminada de ListViewItem:

<Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ListViewItem}"> <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true"> <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> </Border> <ControlTemplate.Triggers> <Trigger Property="IsSelected" Value="true"> <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/> </Trigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsSelected" Value="true"/> <Condition Property="Selector.IsSelectionActive" Value="false"/> </MultiTrigger.Conditions> <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightTextBrushKey}}"/> </MultiTrigger> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter>

Simplemente elimine el Trigger IsSelected y IsSelected / IsSelectionActive MultiTrigger, agregando el siguiente código a su Estilo para reemplazar la plantilla predeterminada, y no habrá cambios visuales cuando se seleccione.

Solución para desactivar los cambios visuales de la propiedad IsSelected:

<Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ListViewItem}"> <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true"> <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> </Border> <ControlTemplate.Triggers> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter>


Bien, un poco tarde para el juego, pero ninguna de estas soluciones hizo lo que yo estaba tratando de hacer. Estas soluciones tienen un par de problemas

  1. Deshabilite ListViewItem, que atornilla los estilos y deshabilita todos los controles de los niños
  2. Eliminar de la pila de prueba de hits, es decir, los controles de los niños nunca pasan el mouse o hacen clic
  3. Hacer que no sea enfocable, ¿esto simplemente no funcionó para mí?

Quería un ListView con los encabezados de agrupación, y cada ListViewItem debería ser simplemente ''informativo'' sin selección o al pasar el mouse sobre él, pero el ListViewItem tiene un botón en el que quiero hacer clic y tener el mouse sobre un lado.

Entonces, realmente lo que quiero es que ListViewItem no sea un ListViewItem en absoluto, así que sobrellevé ControlTemplate de ListViewItem y lo convertí en un simple ContentControl.

<ListView.ItemContainerStyle> <Style TargetType="ListViewItem"> <Setter Property="Template"> <Setter.Value> <ControlTemplate> <ContentControl Content="{Binding Content, RelativeSource={RelativeSource TemplatedParent}}"/> </ControlTemplate> </Setter.Value> </Setter> </Style> </ListView.ItemContainerStyle>


Comentario de Per Martin Konicek, para deshabilitar completamente la selección de los artículos de la manera más simple:

<ListView> <ListView.ItemContainerStyle> <Style TargetType="ListViewItem"> <Setter Property="Focusable" Value="false"/> </Style> </ListView.ItemContainerStyle> ... </ListView>

Sin embargo, si aún necesita la funcionalidad de ListView, como poder seleccionar un elemento, entonces puede deshabilitar visualmente el diseño del elemento seleccionado de esta forma:

Puede hacerlo de varias maneras, desde cambiar ControlTemplate de ListViewItem a simplemente establecer un estilo (mucho más fácil). Puede crear un estilo para ListViewItems utilizando ItemContainerStyle y ''apagar'' el fondo y el pincel de borde cuando se selecciona.

<ListView> <ListView.ItemContainerStyle> <Style TargetType="{x:Type ListViewItem}"> <Style.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter Property="Background" Value="{x:Null}" /> <Setter Property="BorderBrush" Value="{x:Null}" /> </Trigger> </Style.Triggers> </Style> </ListView.ItemContainerStyle> ... </ListView>

Además, a menos que tenga alguna otra forma de notificar al usuario cuando se selecciona el elemento (o solo para probarlo), puede agregar una columna para representar el valor:

<GridViewColumn Header="IsSelected" DisplayMemberBinding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListViewItem}}, Path=IsSelected}" />


Establezca el estilo de cada ListViewItem para que Focusable se establezca en falso.

<ListView ItemsSource="{Binding Test}" > <ListView.ItemContainerStyle> <Style TargetType="{x:Type ListViewItem}"> <Setter Property="Focusable" Value="False"/> </Style> </ListView.ItemContainerStyle> </ListView>


Esto es para otros que pueden cumplir los siguientes requisitos:

  1. Reemplace completamente la indicación visual de "seleccionado" (por ejemplo, use algún tipo de forma), más allá de simplemente cambiar el color del resaltado estándar
  2. Incluya esta indicación seleccionada en DataTemplate junto con las otras representaciones visuales de su modelo, pero,
  3. No desea tener que agregar una propiedad "IsSelectedItem" a su clase de modelo y tener la carga de manipular manualmente esa propiedad en todos los objetos del modelo.
  4. Requiere elementos para ser seleccionables en ListView
  5. También me gustaría reemplazar la representación visual de IsMouseOver

Si eres como yo (usando WPF con .NET 4.5) y descubres que las soluciones que involucran desencadenadores de estilo simplemente no funcionan, esta es mi solución:

Reemplace el ControlTemplate del ListViewItem en un estilo:

<ListView ItemsSource="{Binding MyStrings}" ItemTemplate="{StaticResource dtStrings}"> <ListView.ItemContainerStyle> <Style TargetType="ListViewItem"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ListViewItem"> <ContentPresenter/> </ControlTemplate> </Setter.Value> </Setter> </Style> </ListView.ItemContainerStyle> </ListView>

..Y el DataTemplate:

<DataTemplate x:Key="dtStrings"> <Border Background="LightCoral" Width="80" Height="24" Margin="1"> <Grid > <Border Grid.ColumnSpan="2" Background="#88FF0000" Visibility="{Binding RelativeSource={RelativeSource AncestorType=ListViewItem}, Path=IsMouseOver, Converter={StaticResource conBoolToVisibilityTrueIsVisibleFalseIsCollapsed}}"/> <Rectangle Grid.Column="0" Fill="Lime" Width="10" HorizontalAlignment="Left" Visibility="{Binding RelativeSource={RelativeSource AncestorType=ListViewItem}, Path=IsSelected, Converter={StaticResource conBoolToVisibilityTrueIsVisibleFalseIsCollapsed}}" /> <TextBlock Grid.Column="1" Text="{Binding}" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" /> </Grid> </Border> </DataTemplate>

Resultados en esto en tiempo de ejecución (se selecciona el elemento ''B'', el elemento ''D'' tiene el mouse encima):


La forma más fácil que encontré:

<Setter Property="Focusable" Value="false"/>


La respuesta de Moore no funciona, y la página aquí:

Especificación del color de selección, la alineación de contenido y el color de fondo para elementos en un ListBox

explica por qué no puede funcionar.

Si su vista de lista solo contiene texto básico, la forma más sencilla de resolver el problema es mediante el uso de pinceles transparentes.

<Window.Resources> <Style TargetType="{x:Type ListViewItem}"> <Style.Resources> <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="#00000000"/> <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="#00000000"/> </Style.Resources> </Style> </Window.Resources>

Esto producirá resultados no deseados si las celdas de la lista de lista tienen controles como cuadros combinados, ya que también cambia su color. Para resolver este problema, debe redefinir la plantilla del control.

<Window.Resources> <Style TargetType="{x:Type ListViewItem}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ListViewItem}"> <Border SnapsToDevicePixels="True" x:Name="Bd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}"> <GridViewRowPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Columns="{TemplateBinding GridView.ColumnCollection}" Content="{TemplateBinding Content}"/> </Border> <ControlTemplate.Triggers> <Trigger Property="IsEnabled" Value="False"> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </Window.Resources>


Una de las propiedades de la vista de lista es IsHitTestVisible . Desmárcala


Usa el siguiente código:

<ListView.ItemContainerStyle> <Style TargetType="{x:Type ListViewItem}"> <Setter Property="Background" Value="Transparent`enter code here`" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ListViewItem}"> <ContentPresenter /> </ControlTemplate> </Setter.Value> </Setter> </Style> </ListView.ItemContainerStyle>