首先,免责声明,我正在使用.NET 3.5的虚拟堆栈面板。如果您在未来版本中获得不同的行为,请让我知道。你可以很容易地设置一个带有listviews的测试用例来测试这个问题。
我在虚拟堆栈面板中有一个物品容器样式,将IsSelected属性绑定到视图模型上。
当我选择视图模型中屏幕外的未选择项目,然后滚动到该项目时,数据上下文(视图模式)和实际的listviewitem都具有IsSelected属性为true(期望行为)。该触发器被正确应用于listviewitem并突出显示它。
然而,当我取消选择不在视图中的项目的数据上下文,然后向下滚动直到该项目在视图中,达到项目并创建它时,该项目的数据上下文现在具有IsSelected=true,listviewitem的IsSelected属性也为true,因此listviewitem最终会从触发器中选择矩形(不正确的行为)。
这几乎就像ListViewItem的所有属性在创建项时都被恢复了(这对我来说是有道理的,但是然后它们应该将数据上下文的值绑定到项之后)。
但是似乎并没有发生这种情况。而且,在无法取消选择该项并滚回找到它被选中之后,如果我然后选择/取消选择它,则绑定对该项没有影响。
我看不出来为什么选择视图模型中屏幕外的项目会起作用,而取消选择屏幕外的项目则不会起作用。在两种情况下,新创建的项都应需要重新绑定到视图模型的当前值。但是,一个可以工作而另一个不行。
编辑:啊,好的,所以我不能同时使用回收模式和绑定。谢谢@devhedgehog。我会给你奖励,但你需要一个答案。我发誓我之前已经尝试过了,但也许之前我没有处理绑定列表视图中的点击事件,所以我在物理选择时破坏了绑定或其他原因。我记得在某个时候尝试了两种模式,但可能有其他东西干扰了它,所以它无法工作。反正现在它能用了。
由于您提到它,我希望最好避免保留不必要的代码,并从VirtualizingPanel而不是VirtualizingStackPanel继承。但是我想能够设置水平滚动范围,这需要我重新实现IScrollInfo。但是,我无法让虚拟堆栈面板与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>