绑定到VirtualizingStackPanel上的数据中断

时间:2014-01-30 01:54:17

标签: c# wpf panel virtualization virtualizingstackpanel

首先,免责声明,我正在使用.net 3.5的virtualizingstackpanel。如果您在将来的版本中有不同的行为,请告诉我。使用listviews设置测试用例相对简单,您可以对其进行测试。

我在virtualizingstackpanel中有一个itemcontainer样式,它将属性IsSelected绑定到viewmodel。

当我在视图模型中选择一个未选择的项目在屏幕外,然后滚动到该项目时,datacontext(viewmode)和实际listviewitem都将IsSelected属性设置为true(预期行为)。触发器正确应用于listviewitem,突出显示它。

但是,当我取消选择不在视图中的项目的datacontext然后向下滚动直到该项目在视图中时,在到达项目并创建它时,项目的datacontext现在具有IsSelected = true和listviewitem的IsSelected属性也是如此,因此listviewitem以触发器中的选择矩形结束(不正​​确的行为)。

这几乎就像ListViewItem的属性在创建项目时都被恢复一样(这对我来说很有意义,但是之后他们应该将datacontext的值绑定到项目之后)。

但这似乎并没有发生。此外,未能取消选择该项目并向后滚动以找到它。如果我然后选择/取消它,绑定对该项目没有影响。

我无法看到为什么在视图模型中选择屏幕外的项目而不是在我取消选择屏幕外项目时它的工作原理。在这两种情况下,新创建的项目都需要反弹到viewmodel的当前值。但是,一个有效,另一个没有。

任何帮助或想法都将不胜感激。

编辑: 好的,所以我只是不能使用回收模式和绑定它似乎。谢谢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>

1 个答案:

答案 0 :(得分:1)

这个问题实际上似乎得到了回答似乎很奇怪,但却被列为没有答案。所以我会在这里发表dev hedgehog的评论/答案。

  

请在没有自定义度量的情况下使用标准的VirtualizingStackPanel   逻辑。你的逻辑中没有任何特别的东西   VirtualizingStackPanel不能这样做。而RecyclingMode不应该   回收,但将其遗漏或更改为标准。