首先,免责声明,我正在使用 .net 3.5 的 virtualizingstackpanel。如果您在以后的版本中有不同的行为,请告诉我。使用列表视图设置测试用例相对简单,您可以对其进行测试。
我在将属性 IsSelected 绑定到视图模型的 virtualizingstackpanel 中有一个 itemcontainer 样式。
当我在屏幕外的视图模型中选择一个未选择的项目,然后滚动到该项目时,数据上下文(视图模式)和实际的列表视图项都将 IsSelected 属性设置为 true(预期行为)。触发器正确地应用于突出显示它的列表视图项。
但是,当我取消选择不在视图中的项目的数据上下文然后向下滚动直到项目在视图中时,到达项目并创建它时,项目的数据上下文现在具有 IsSelected = true 并且 listviewitem 的 IsSelected 属性也是 true ,因此 listviewitem 以触发器的选择矩形结束(不正确的行为)。
就好像 ListViewItem 的属性在创建项目时全部恢复(这对我来说很有意义,但随后它们应该将数据上下文的值绑定到项目)。
但这似乎并没有发生。此外,在未能取消选择该项目并向后滚动以找到它被选中后。如果我然后选择/删除它,则绑定对项目没有影响。
我看不出为什么在视图模型中选择屏幕外的项目时它会起作用,而不是当我取消选择屏幕外的项目时它会起作用。在这两种情况下,新创建的项目都需要重新绑定到视图模型的当前值。但是,一个有效,另一个无效。
编辑:啊,好吧,所以我似乎不能使用回收模式和绑定。谢谢@devhedgehog。会给你赏金,但你需要一个答案。我发誓我早些时候尝试过,但也许我之前没有处理绑定列表视图中的点击事件,所以我打破了物理选择或其他东西的绑定。我确实记得曾经尝试过两种模式,但可能有其他干扰,所以它不起作用。无论如何,它现在有效。
既然你提到它,我想最好避免保留不必要的代码并从 virtualizingstackpanel 继承而不是虚拟化面板。但是我希望能够设置水平滚动范围,这需要我重新实现Iscrollinfo。但是,我无法让 virtualizingstackpanel 与 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>