首页 > 其他分享 >WPF VirtualizingPanel.CacheLength="1" VirtualizingPanel.CacheLengthUnit="Item" c

WPF VirtualizingPanel.CacheLength="1" VirtualizingPanel.CacheLengthUnit="Item" c

时间:2024-10-05 19:33:17浏览次数:1  
标签:string CacheLengthUnit Windows VirtualizingPanel System CacheLength using get pu

 <ListBox ItemsSource="{Binding BooksCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
          SelectedIndex="{Binding ImgIdx,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
          VirtualizingPanel.IsVirtualizing="True"
          VirtualizingPanel.IsContainerVirtualizable="True"
          VirtualizingPanel.CacheLength="1"
          VirtualizingPanel.CacheLengthUnit="Item"
          VirtualizingPanel.VirtualizationMode="Recycling"
          >
     <behavior:Interaction.Triggers>
         <behavior:EventTrigger EventName="SelectionChanged">
             <behavior:CallMethodAction MethodName="ListBox_SelectionChanged" TargetObject="{Binding}"/>
         </behavior:EventTrigger>
     </behavior:Interaction.Triggers>
     <ListBox.ItemTemplate>
         <DataTemplate>
             <local:ImgTbk Width="{Binding ActualWidth,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}"
                           Height="{Binding ActualHeight,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}"
                 UCImgUrl="{Binding DataContext.ImgUrl,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}}}"
                           UCStr="{Binding DataContext.Id,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}}}"
                           RenderOptions.CacheInvalidationThresholdMaximum="2"/>
         </DataTemplate>
     </ListBox.ItemTemplate>
 </ListBox>

 

 

 

 

 

 

 

 

//u

 usercontrol

//usercontrol.xaml
<UserControl x:Class="WpfApp11.ImgTbk"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfApp11"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <Image Source="{Binding UCImgUrl,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                  />
        <TextBlock Text="{Binding UCStr,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                   HorizontalAlignment="Center"
                   VerticalAlignment="Center"
                   FontSize="50"
                   Foreground="Red"/>
    </Grid>
</UserControl>


//uercontrol.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp11
{
    /// <summary>
    /// Interaction logic for ImgTbk.xaml
    /// </summary>
    public partial class ImgTbk : UserControl
    {
        public ImgTbk()
        {
            InitializeComponent();
            this.DataContext = this;
        }


        public string UCImgUrl
        {
            get { return (string)GetValue(UCImgUrlProperty); }
            set { SetValue(UCImgUrlProperty, value); }
        }

        // Using a DependencyProperty as the backing store for UCImgUrl.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty UCImgUrlProperty =
            DependencyProperty.Register("UCImgUrl", typeof(string), 
                typeof(ImgTbk), new PropertyMetadata(""));




        public string UCStr
        {
            get { return (string)GetValue(UCStrProperty); }
            set { SetValue(UCStrProperty, value); }
        }

        // Using a DependencyProperty as the backing store for UCStr.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty UCStrProperty =
            DependencyProperty.Register("UCStr", typeof(string), 
                typeof(ImgTbk), new PropertyMetadata(""));

    }
}





//xaml
<Window x:Class="WpfApp11.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:behavior="http://schemas.microsoft.com/xaml/behaviors"
        xmlns:local="clr-namespace:WpfApp11"
        mc:Ignorable="d"
        WindowState="Maximized"
        Title="MainWindow" Height="450" Width="800">
    <behavior:Interaction.Triggers>
        <behavior:EventTrigger EventName="Loaded">
            <behavior:CallMethodAction MethodName="Window_Loaded" TargetObject="{Binding}"/>
        </behavior:EventTrigger>
    </behavior:Interaction.Triggers>
    <Window.DataContext>
        <local:BookVM/>
    </Window.DataContext>
    <Grid>
        <ListBox ItemsSource="{Binding BooksCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                 SelectedIndex="{Binding ImgIdx,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                 VirtualizingPanel.IsVirtualizing="True"
                 VirtualizingPanel.IsContainerVirtualizable="True"
                 VirtualizingPanel.CacheLength="1"
                 VirtualizingPanel.CacheLengthUnit="Item"
                 VirtualizingPanel.VirtualizationMode="Recycling"
                 >
            <behavior:Interaction.Triggers>
                <behavior:EventTrigger EventName="SelectionChanged">
                    <behavior:CallMethodAction MethodName="ListBox_SelectionChanged" TargetObject="{Binding}"/>
                </behavior:EventTrigger>
            </behavior:Interaction.Triggers>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <local:ImgTbk Width="{Binding ActualWidth,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}"
                                  Height="{Binding ActualHeight,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}"
                        UCImgUrl="{Binding DataContext.ImgUrl,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}}}"
                                  UCStr="{Binding DataContext.Id,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}}}"
                                  RenderOptions.CacheInvalidationThresholdMaximum="2"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>






//xaml.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using System.Threading;
using System.Windows.Threading;

namespace WpfApp11
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            RenderOptions.ProcessRenderMode = System.Windows.Interop.RenderMode.Default;
            Application.Current.DispatcherUnhandledException += Current_DispatcherUnhandledException;
            
        }

        private void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            MessageBox.Show(e.Exception.Message);
        }
    }
    public class BookVM : INotifyPropertyChanged
    {

        public BookVM()
        {
            InitData();            
        }

        private void InitTimer()
        {
            System.Timers.Timer tmr = new System.Timers.Timer();
            tmr.Elapsed += Tmr_Elapsed;
            tmr.Interval = 200;
            tmr.Start();
        }

        private void Tmr_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            ++ImgIdx;           
        }

        private void InitData()
        {
            imgsList = new List<string>(Directory.GetFiles(@"../../Images"));
            if(imgsList!=null && imgsList.Any())
            {
                int imgsCount=imgsList.Count;
                BooksCollection = new ObservableCollection<Book>();
                for(int i=0;i<100000;i++)
                {
                    BooksCollection.Add(new Book()
                    {
                        Id = i + 1,
                        Name = $"Name_{i + 1}",
                        ImgUrl = $"{imgsList[i% imgsCount]}"
                    });
                }
            }
        }

        public void Window_Loaded(object sender, RoutedEventArgs e)
        {
            Thread.Sleep(2000);
            InitTimer();
        }

        public void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if(e!=null && e.AddedItems!=null && e.AddedItems.Count>0)
            {
                var bk = e.AddedItems[0] as Book;
                if(bk!=null)
                {
                    var listBox = sender as ListBox;
                    if (listBox != null)
                    {
                        Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() =>
                        {
                            listBox.ScrollIntoView(bk);
                        }));
                    }
                }
            }
        }


        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propName)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler?.Invoke(this, new PropertyChangedEventArgs(propName));
            }
        }

        private List<string> imgsList { get; set; }

        private ObservableCollection<Book> booksCollection;
        public ObservableCollection<Book> BooksCollection
        {
            get
            {
                return booksCollection;
            }
            set
            {
                if(value!=booksCollection)
                {
                    booksCollection = value;
                    OnPropertyChanged(nameof(BooksCollection));
                }
            }
        }

        private int imgIdx;
        public int ImgIdx
        {
            get
            {
                return imgIdx;
            }
            set
            {
                if(value!=imgIdx)
                {
                    imgIdx = value;
                    OnPropertyChanged(nameof(ImgIdx));
                    if(ImgIdx>=BooksCollection.Count)
                    {
                        ImgIdx = 0;
                    }
                }
            }
        }
    }

    public class Book
    {
        public int Id { get; set; }

        public string Name { get; set; }

        public string ImgUrl { get; set; }
    }
}

 

标签:string,CacheLengthUnit,Windows,VirtualizingPanel,System,CacheLength,using,get,pu
From: https://www.cnblogs.com/Fred1987/p/18448342

相关文章

  • WPF VirtualizingPanel 实现UI虚拟化
    当需要优化ItemsControl的性能时,使用VirtualizingPanel。优点是不会为面板的所有子元素创建相应的UI元素,而只会为显示的那些子元素创建相应的UI元素。尤其是元素多的情况下,这会导致性能上的巨大差异。VirtualizingPanel类中实现以下几项依赖属性。CacheLength/CacheLeng......