C# 绑定到VirtualzingStackPanel上的数据中断

C# 绑定到VirtualzingStackPanel上的数据中断,c#,wpf,panel,virtualization,virtualizingstackpanel,C#,Wpf,Panel,Virtualization,Virtualizingstackpanel,首先是免责声明,我正在使用.NET3.5的VirtualzingStackPanel。如果你在未来的版本中有不同的行为,请告诉我。使用ListView设置一个测试用例相对简单,您可以对其进行测试 我在VirtualzingStackPanel中有一个itemcontainer样式,它将属性IsSelected绑定到viewmodel 当我在屏幕外的视图模型中选择一个未选中的项目,然后滚动到该项目时,datacontext(viewmode)和实际listviewitem的IsSelected属性

首先是免责声明,我正在使用.NET3.5的VirtualzingStackPanel。如果你在未来的版本中有不同的行为,请告诉我。使用ListView设置一个测试用例相对简单,您可以对其进行测试

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

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

但是,当我为不在视图中的项取消选择datacontext,然后向下滚动直到该项在视图中时,在到达该项并创建该项时,该项的datacontext现在具有IsSelected=true,listviewitem的IsSelected属性也为true,因此listviewitem最终会从触发器中选择一个矩形(不正确的行为)

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

但这似乎没有发生。此外,在取消选择项目失败并向后滚动以找到已选择的项目后。如果我随后选择/取消选择它,则绑定对该项目没有影响

我看不出为什么在viewmodel中选择屏幕外的项目时以及取消屏幕外的项目时,它会起作用的逻辑原因。在这两种情况下,新创建的项目都需要恢复到viewmodel的当前值。但是,一个有效,另一个无效

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

编辑: 啊,好吧,看来我就是不能使用循环模式和绑定。谢谢devhedgehog。我会给你奖金,但你需要一个答案。我发誓我以前试过,但可能我以前没有在绑定列表视图中处理单击事件,所以我在物理选择或其他方面破坏了绑定。我确实记得一次尝试了两种模式重点是,但可能有其他干扰,所以它不起作用。不管怎样,它现在起作用了

既然您提到了它,我希望最好避免保留不必要的代码并从VirtualzingStackPanel继承,而不是从Virtualization panel继承。但我希望能够设置水平滚动范围,这需要我重新实现ISCRLLINFO。然而,我在让VirtualzingStackPanel与isc良好交互方面遇到了困难罗尔信息

      <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>

奇怪的是,这个问题似乎已经得到了回答,但却被列为没有答案。因此,我将在这里发布您的评论/答案


请使用无需定制尺寸的标准VirtualzingStackPanel 逻辑。在你的逻辑中没有什么特别的地方 VirtualzingStackPanel无法执行。并且不应禁用回收模式 循环使用,但不要使用或改为标准


你为什么不使用VirtualzingStackPanel的measureoverride?VirtualzingStackPanel会解决这个问题。顺便说一句,我检查了你的measureoverride方法,你缺少VirtualzingStackPanel的功能。你没有包括偏移量。你没有跟踪重点元素。当你处于回收模式时,你需要在之前和之后进行清理在测量其他子元素后,元素将以wront顺序插入…因此我使用了一个关于创建虚拟化平铺面板的教程,该测量值就是在那里使用的。很抱歉,我忘了链接它。我将编辑我的帖子。此外,我在“清理项目”功能中负责清理。我不知道您指的是什么偏移量。可以吗你发布了一个到虚拟化堆栈面板measureoverride的链接吗?不管怎样,我目前在虚拟化面板上遇到的唯一问题是,你不能在一个不存在的项目上设置IsSelected。你必须在viewmodel中更改它。但是,我不知道如何将样式中的绑定应用到当前的正确viewmodel已尝试调用applytemplate(FrameworkElement)新创建项目后,请在ListViewItem上单击,但如果没有自定义测量逻辑,请使用标准的VirtualzingStackPanel。您在逻辑中添加的任何特殊功能都不是VirtualzingStackPanel无法做到的。并且RecyclingMode不应为Recycle,而应将其忽略或更改为standard。没有您,您很难理解t演示。请上传演示。你知道,我们喜欢看代码示例。答案是否定的,VSP按单位滚动。这意味着它可以跳过项目。但是它有按像素滚动的功能。如果你使用.NET 4.5,你将能够激活该功能。但是你在3.5中。在.NET 3.5中,只有TreeView允许按像素滚动。这意味着如果你想要平滑滚动