//xaml <Window x:Class="WpfApp6.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:local="clr-namespace:WpfApp6" mc:Ignorable="d" WindowState="Maximized" WindowStyle="None" KeyDown="Window_KeyDown" Title="MainWindow" Height="450" Width="800"> <Grid> <ListBox x:Name="lbx" ItemsSource="{Binding BooksCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding SelectedBook,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" VirtualizingPanel.IsContainerVirtualizable="True" VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.CacheLengthUnit="Item" VirtualizingPanel.VirtualizationMode="Recycling" SelectionChanged="lbx_SelectionChanged"> <ListBox.ItemTemplate> <DataTemplate> <Image Source="{Binding DataContext.ImgUrl,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBoxItem}}}" Width="{Binding ActualWidth,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}" Height="{Binding ActualHeight,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}" /> </DataTemplate> </ListBox.ItemTemplate> </ListBox> <TextBlock HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="150" FontSize="50" Foreground="Red" x:Name="tbk"/> </Grid> </Window> //xaml.cs using System; using System.Collections.Generic; using System.Collections.ObjectModel; 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.ComponentModel; namespace WpfApp6 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window, INotifyPropertyChanged { public MainWindow() { InitializeComponent(); Application.Current.DispatcherUnhandledException += Current_DispatcherUnhandledException; //RenderOptions.ProcessRenderMode = System.Windows.Interop.RenderMode.Default; this.DataContext = this; Loaded += MainWindow_Loaded; } private void MainWindow_Loaded(object sender, RoutedEventArgs e) { tbk.Text = "1"; BooksCollection = new ObservableCollection<Book>(); var imgsList = Directory.GetFiles(@"../../Images"); if (imgsList != null && imgsList.Any()) { int imgsCount = imgsList.Count(); for (int i = 0; i < 100; i++) { BooksCollection.Add(new Book() { Id = i + 1, Name = $"Name_{i + 1}", ImgUrl = imgsList[i % imgsCount], }); } } System.Timers.Timer tmr = new System.Timers.Timer(); tmr.Interval = 100; tmr.Elapsed += Tmr_Elapsed; tmr.Start(); } private void Current_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) { MessageBox.Show(e.Exception.Message); } public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propName) { var handler = PropertyChanged; if(handler!=null) { handler?.Invoke(this, new PropertyChangedEventArgs(propName)); } } private Book selectedBook; public Book SelectedBook { get { return selectedBook; } set { if(value!= selectedBook) { selectedBook = value; OnPropertyChanged(nameof(SelectedBook)); } } } private ObservableCollection<Book> books; public ObservableCollection<Book> BooksCollection { get { return books; } set { if(value!=books) { books = value; OnPropertyChanged(nameof(BooksCollection)); } } } private void Tmr_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { Dispatcher.BeginInvoke(new Action(() => { if (++lbx.SelectedIndex >= lbx.Items.Count) { lbx.SelectedIndex = 0; } var bk= BooksCollection[lbx.SelectedIndex]; if (bk!=null) { tbk.Text = bk.Id.ToString(); SelectedBook = bk; lbx.ScrollIntoView(SelectedBook); } })); } private void Window_KeyDown(object sender, KeyEventArgs e) { if (Keyboard.Modifiers == ModifierKeys.Control && e.Key == Key.C) { var msgResult = MessageBox.Show("Are you sure to exit?", "Exit", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes); if (msgResult == MessageBoxResult.Yes) { Application.Current.Shutdown(); } } } private void lbx_SelectionChanged(object sender, SelectionChangedEventArgs e) { if(e.AddedItems!=null && e.AddedItems.Count>0) { var bk = e.AddedItems[0] as Book; if (bk!=null) { SelectedBook = bk; lbx.ScrollIntoView(SelectedBook); } } } } public class Book { public int Id { get; set; } public string Name { get; set; } public string ImgUrl { get; set; } } }