开发者

Setting Listbox VirtualizationMode (Data)

开发者 https://www.devze.com 2023-03-04 09:28 出处:网络
I am binding IList<T> to the listbox and expect it to load only the needed data (visible) <Window.Resources>

I am binding IList<T> to the listbox and expect it to load only the needed data (visible)

 <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="listbo开发者_开发知识库x1" 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;
}

When I run the application, indexer is invoked 100 times (per every item in list)but it should invoke just for items in list.


You can have data virtualization as well, just use a 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);
    }
}

Then just the visible item will be queried. (you can also implement a custom CollectionView, a lot of things are overrideable there)

Edit: You can also implement IList as well, WPF seems to check for IList and IList is not an IList.


The virtualization support in WPF is for the UI only. This means it will still iterate over all the data items, but will only create UIElements to display those items as needed.

In general when virtualization is enabled, scrolling is actually done item-by-item, instead of pixel-by-pixel. In order for it to know the scrolling limits when scrolling item-by-item, it must know the total number of items.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号