2011-05-05 28 views
2

我绑定IList<T>到列表框中,并期望它仅加载所需要的数据(可视)设置列表框VirtualizationMode(数据)

<Window.Resources> 
     <Style x:Key="lStyle" TargetType="{x:Type ListBox}"> 
      <Setter Property="VirtualizingStackPanel.IsVirtualizing" Value="True"/> 
      <Setter Property="VirtualizingStackPanel.VirtualizationMode" Value="Recycling"/>   
      <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Visible"/>   
     </Style> 
    </Window.Resources> 
    <Grid Height="Auto" Width="Auto">  
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="Auto" /> 
      <ColumnDefinition Width="Auto" />   
     </Grid.ColumnDefinitions> 
     <ListBox Name="listbox1" ItemsSource="{Binding}" Grid.Column="0" Grid.Row="0" 
       Style="{DynamicResource lStyle}" Height="165" Margin="0,0,0,98" Width="296"> 
      <ListBox.ItemTemplate> 
       <DataTemplate> 
        <StackPanel Orientation="Horizontal" > 
         <Label Width="100" Content="{Binding Path=Name}"></Label> 
         <Label Width="100" Content="{Binding Path=Age}"></Label> 
        </StackPanel> 

       </DataTemplate> 

      </ListBox.ItemTemplate> 

     </ListBox> 
    </Grid> 






class MyCollection<T> : IList<T> where T : class //Just the relevant part 
    { 
     private List<T> _list = new List<T>(); 

     public List<T> List 
     { 
      get { return _list; } 
      set { _list = value; } 
     } 
     public T this[int index] 
     { 
      get 
      { 
       Trace.WriteLine("Index: " + index); 
       return _list[index]; 
      } 
      set 
      { 
       throw new NotImplementedException(); 
      } 
    } 


MyCollection<Person> mycollection1; 
public Window1() 
{ 
    InitializeComponent(); 
    mycollection1 = new MyCollection<Person>(); 

    for (int i = 0; i < 100; i++) 
    { 
     mycollection1.Add(new Person { Name = "Tom", Age = 33 }); 
    } 

      this.DataContext = mycollection1; 
} 

当我运行应用程序,索引被引用100次(每10项目在列表中),但它应该只为列表中的项目调用。

回答

0

你可以有数据虚拟化,以及,只需使用的ListCollectionView:

public class MyCollection<T> : ListCollectionView 
{ 
    public MyCollection(List<T> list) 
     : base(list) 
    { 
    } 

    public override object GetItemAt(int index) 
    { 
     Debug.WriteLine(index); 
     return base.GetItemAt(index); 
    } 
} 

然后只是有形的项目将被查询。 (你也可以实现一个自定义的CollectionView,很多东西都可以被覆盖)

编辑:你也可以实现IList,WPF似乎检查IList和IList不是IList。

+0

为什么我不能使用IList?我可以使用任何其他接口吗? – 2011-05-05 18:05:56

+0

为什么所有指数都被触发? – 2011-05-05 18:10:47

+0

嗯,WPF检查IList(没有泛型),IList 不是IList。将IList添加到MyCollection也应该可以。 – kowd 2011-05-05 18:14:35

0

WPF中的virtualization support仅用于UI。这意味着它仍会遍历所有数据项,但只会创建UIElements以根据需要显示这些项目。

通常,启用虚拟化时,滚动实际上是逐项完成的,而不是逐个像素。为了让它在逐项滚动时知道滚动限制,它必须知道项目的总数。