c# - not - Enlace a la ruptura de datos en VirtualizingStackPanel
title link (1)
En primer lugar, un descargo de responsabilidad, estoy trabajando con el panel de virtualización de .net 3.5. Si tienes un comportamiento diferente en futuras versiones, házmelo saber. Es relativamente sencillo configurar un caso de prueba con vistas de lista con las que puede probar esto.
Tengo un estilo de contenedor de elementos en un virtualizingstackpanel que enlaza la propiedad IsSelected al viewmodel.
cuando selecciono un elemento no seleccionado en el modelo de vista que está fuera de la pantalla y luego me desplazo hacia ese elemento, tanto el contexto de datos (modo de vista) como el elemento de vista de lista real tienen la propiedad IsSelected como verdadera (comportamiento esperado). El desencadenador se aplica correctamente a la lista de elementos de vista que lo resalta.
Sin embargo, cuando deselecciono el origen de datos para un elemento que no está a la vista y luego me desplazo hacia abajo hasta que el elemento esté a la vista, al alcanzar el elemento y crearlo, el datacontext del elemento ahora tiene IsSelected = true y la propiedad IsSelected de listviewitem también es verdadera , por lo que listviewitem termina con un rectángulo de selección desde el activador (comportamiento incorrecto).
Es casi como si las propiedades de ListViewItem se restauraran al crear el elemento (esto tiene sentido para mí, pero luego deben vincular los valores del contexto de datos con el elemento posterior).
Pero eso no parece estar sucediendo. Además, después de no poder deseleccionar el elemento y desplazarse hacia atrás para encontrarlo seleccionado. Si luego lo selecciono / desecito, el enlace no tiene efecto en el artículo.
No veo ninguna razón lógica por la que funcionaría al seleccionar un elemento en el modelo de vista que está fuera de la pantalla y no cuando Deselecciono un elemento fuera de la pantalla. En ambos casos, el elemento recién creado debe ser rebotado al valor actual del modelo de vista. Sin embargo, uno funciona y el otro no.
Cualquier ayuda o pensamiento sería apreciado.
Edit: Ah, ok, entonces no puedo usar el modo de reciclaje y el enlace parece. Gracias devhedgehog. Te daría la recompensa pero necesitas una respuesta. Juro que lo intenté antes, pero tal vez no estaba manejando los eventos de clic en la vista de lista enlazada antes, de modo que estaba rompiendo el enlace en la selección física o algo así. Recuerdo haber intentado ambos modos en un momento dado, pero probablemente hubo algo más que interfirió para que no funcionara. De todos modos funciona ahora.
Como lo mencionó, me gustaría preferiblemente evitar mantener código innecesario y heredar de virtualizingstackpanel en lugar de virtualizar el panel. Pero quiero poder establecer la extensión del desplazamiento horizontal, lo que requiere que vuelva a implementar Iscrollinfo. Sin embargo, estaba teniendo problemas para conseguir que virtualizingstackpanel interactúe bien con iscrollinfo
<ListView
x:Name="TestLV"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Background="Green"
ItemsSource="{Binding Path=AddedItems, Mode=OneWay}"
SnapsToDevicePixels="True"
VirtualizingStackPanel.VirtualizationMode="Recycling"
VirtualizingStackPanel.IsVirtualizing="true"
ScrollViewer.IsDeferredScrollingEnabled="False"
Grid.Column ="4"
MouseDown="TestLV_MouseDown"
>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=OneWay}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Grid
x:Name="SignalGrid"
Background="Transparent"
>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border
Name="Bd"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
SnapsToDevicePixels="true">
<ContentPresenter
x:Name="PART_Header"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
/>
</Border>
<ItemsPresenter
x:Name="ItemsHost"
Grid.Row="1"
Grid.Column="0"
/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected"
Value="false">
<Setter
TargetName="SignalGrid"
Property="Background"
Value="Transparent"
/>
</Trigger>
<Trigger Property="IsSelected"
Value="true">
<Setter
TargetName="SignalGrid"
Property="Background"
Value="Navy"
/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
<!--<Components:VirtualizingTilePanel
ChildSize="{Binding Path=GraphHeight}"
/>-->
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.Template>
<ControlTemplate>
<Grid >
<ScrollViewer
>
<ItemsPresenter />
</ScrollViewer>
</Grid>
</ControlTemplate>
</ListView.Template>
<!--Template Defining the layout of items in this treeview-->
<ListView.Resources>
<HierarchicalDataTemplate
ItemsSource ="{Binding Path = bits}"
DataType="{x:Type ViewModels:BusViewModel}"
>
<Grid>
<Components:CenteredTextBlock
x:Name="CommentTextBlock"
Foreground="Black"
BorderThickness="{Binding RelativeSource ={RelativeSource AncestorType={x:Type ListView}}, Path=BorderThickness}"
BorderBrush="{Binding RelativeSource ={RelativeSource AncestorType={x:Type ListView}}, Path=BorderBrush}"
HorizontalAlignment="Stretch"
Height="{Binding ElementName=graph_viewer, Path=GraphHeight, Mode=OneWay}"
>
<Components:CenteredTextBlock.MainText>
<MultiBinding Converter="{StaticResource StringConcatConverter}">
<Binding Path="Alias" />
<Binding Path="SignalValueAtPrimaryMarker" />
</MultiBinding>
</Components:CenteredTextBlock.MainText>
</Components:CenteredTextBlock>
</Grid>
</HierarchicalDataTemplate>
<DataTemplate
DataType="{x:Type ViewModels:BitViewModel}"
>
<Grid>
<Components:CenteredTextBlock
Foreground="Black"
BorderThickness="{Binding RelativeSource ={RelativeSource AncestorType={x:Type ListView}}, Path=BorderThickness}"
BorderBrush="{Binding RelativeSource ={RelativeSource AncestorType={x:Type ListView}}, Path=BorderBrush}"
HorizontalAlignment="Stretch"
Height="{Binding ElementName=graph_viewer, Path=GraphHeight, Mode=OneWay}">
<Components:CenteredTextBlock.MainText>
<MultiBinding Converter="{StaticResource StringConcatConverter}">
<Binding Path="Alias" />
<Binding Path="SignalValueAtPrimaryMarker" />
</MultiBinding>
</Components:CenteredTextBlock.MainText>
</Components:CenteredTextBlock>
</Grid>
</DataTemplate>
<DataTemplate
DataType="{x:Type ViewModels:SelectableItemViewModel}"
>
<Grid>
<Components:CenteredTextBlock
Foreground="Red"
BorderThickness="{Binding RelativeSource ={RelativeSource AncestorType={x:Type ListView}}, Path=BorderThickness}"
BorderBrush="{Binding RelativeSource ={RelativeSource AncestorType={x:Type ListView}}, Path=BorderBrush}"
HorizontalAlignment="Stretch"
Height="{Binding ElementName=graph_viewer, Path=GraphHeight, Mode=OneWay}"
MainText="{Binding Path = FullName}"
/>
</Grid>
</DataTemplate>
</ListView.Resources>
</ListView>
Parece extraño que esta pregunta parezca haber sido contestada, pero que aparece como que no tiene respuesta. Así que voy a publicar el comentario / respuesta de dev hedgehog aquí.
Utilice el VirtualizingStackPanel estándar sin su lógica de medida personalizada. No hay nada que hayas agregado en tu lógica que VirtualizingStackPanel no pueda hacer. Y RecyclingMode no debe ser Reciclar, sino dejarlo o cambiarlo a Estándar.