@@ -57,23 +57,23 @@ public sealed partial class Thumbnails : IDisposable
5757 public static readonly DependencyProperty DependencyThumbHeight = DependencyProperty . Register (
5858 nameof ( DependencyThumbHeight ) ,
5959 typeof ( int ) ,
60- typeof ( Thumbnails ) , new PropertyMetadata ( 100 ) ) ;
60+ typeof ( Thumbnails ) ) ;
6161
6262 /// <summary>
6363 /// The Thumb Length (in lines)
6464 /// </summary>
6565 public static readonly DependencyProperty DependencyThumbWidth = DependencyProperty . Register (
6666 nameof ( DependencyThumbWidth ) ,
6767 typeof ( int ) ,
68- typeof ( Thumbnails ) , new PropertyMetadata ( 100 ) ) ;
68+ typeof ( Thumbnails ) ) ;
6969
7070 /// <summary>
7171 /// The Thumb Cell Size
7272 /// </summary>
7373 public static readonly DependencyProperty DependencyThumbCellSize = DependencyProperty . Register (
7474 nameof ( DependencyThumbCellSize ) ,
7575 typeof ( int ) ,
76- typeof ( Thumbnails ) , new PropertyMetadata ( 100 ) ) ;
76+ typeof ( Thumbnails ) ) ;
7777
7878 /// <summary>
7979 /// The dependency thumb grid
@@ -144,6 +144,11 @@ public sealed partial class Thumbnails : IDisposable
144144 /// </summary>
145145 private int _originalHeight ;
146146
147+ /// <summary>
148+ /// The loaded
149+ /// </summary>
150+ private bool _loaded ;
151+
147152 /// <summary>
148153 /// The original width
149154 /// </summary>
@@ -448,92 +453,102 @@ private async Task OnItemsSourceChanged()
448453 /// </summary>
449454 /// <param name="sender">The source of the event.</param>
450455 /// <param name="e">The <see cref="RoutedEventArgs" /> instance containing the event data.</param>
451- private async void UserControl_Loaded ( object sender , RoutedEventArgs e )
456+ private void UserControl_Loaded ( object sender , RoutedEventArgs e )
452457 {
453458 try
454459 {
460+ _loaded = true ;
461+
462+ // Capture original width/height immediately
455463 _originalWidth = ThumbWidth ;
456464 _originalHeight = ThumbHeight ;
457465
458- await LoadImages ( ) ; // safe to await here
466+ // Start loading images asynchronously
467+ if ( ItemsSource != null )
468+ {
469+ _ = LoadItemsAsync ( ) ;
470+ }
459471 }
460472 catch ( Exception ex )
461473 {
462- // Log or handle exceptions gracefully
463- Trace . WriteLine ( $ "Error loading images: { ex } ") ;
474+ Trace . WriteLine ( $ "Error in Loaded: { ex } ") ;
464475 }
465476 }
466477
478+ /// <summary>
479+ /// Fire-and-forget wrapper to call your async method
480+ /// Loads the items asynchronous.
481+ /// </summary>
482+ private async Task LoadItemsAsync ( )
483+ {
484+ await OnItemsSourceChanged ( ) ;
485+ }
486+
467487 /// <summary>
468488 /// Loads the images.
469489 /// </summary>
470490 private async Task LoadImages ( )
471491 {
472492 if ( ItemsSource ? . Any ( ) != true ) return ;
473493
494+ _cancellationTokenSource ? . Cancel ( ) ;
474495 _cancellationTokenSource = new CancellationTokenSource ( ) ;
475496 var token = _cancellationTokenSource . Token ;
476497
498+ var timer = Stopwatch . StartNew ( ) ;
477499
478-
479- var timer = new Stopwatch ( ) ;
480- timer . Start ( ) ;
481-
482- // Initiate all values
483- ExtendedGrid . CellSize = ThumbCellSize ;
500+ // Make a local copy of images
484501 var pics = new Dictionary < int , string > ( ItemsSource ) ;
502+
503+ // Initialize dictionaries
485504 Keys = new ConcurrentDictionary < string , int > ( ) ;
486505 ImageDct = new ConcurrentDictionary < string , Image > ( ) ;
487506 Border = new ConcurrentDictionary < int , Border > ( ) ;
488507 Selection = new ConcurrentDictionary < int , bool > ( ) ;
489508 if ( SelectBox ) ChkBox = new ConcurrentDictionary < int , CheckBox > ( ) ;
490509
510+ // Capture initial values from dependency properties
491511 int cellSize = await Application . Current . Dispatcher . InvokeAsync ( ( ) => ThumbCellSize ) ;
492512 int thumbWidth = await Application . Current . Dispatcher . InvokeAsync ( ( ) => ThumbWidth ) ;
493513 int thumbHeight = await Application . Current . Dispatcher . InvokeAsync ( ( ) => ThumbHeight ) ;
514+ bool thumbGrid = await Application . Current . Dispatcher . InvokeAsync ( ( ) => ThumbGrid ) ;
494515
495- // Handle special cases
496- if ( cellSize == 0 )
497- {
498- cellSize = 100 ;
499- }
516+ // --- Handle special cases ---
517+ if ( cellSize <= 0 ) cellSize = 100 ;
518+ if ( thumbHeight <= 0 && thumbWidth <= 0 ) thumbHeight = 1 ;
500519
501- if ( thumbHeight == 0 && thumbWidth == 0 )
520+ if ( thumbHeight * thumbWidth < pics . Count )
502521 {
503- thumbHeight = 1 ;
504- }
505-
506- if ( ThumbHeight * thumbWidth < pics . Count )
507- {
508- if ( thumbWidth == 1 )
509- {
510- thumbHeight = pics . Count ;
511- }
512-
513- if ( thumbHeight == 1 )
514- {
515- thumbWidth = pics . Count ;
516- }
522+ // Only one row or one column
523+ if ( thumbWidth == 1 ) thumbHeight = pics . Count ;
524+ if ( thumbHeight == 1 ) thumbWidth = pics . Count ;
517525
526+ // Neither is 1 → calculate width based on height
518527 if ( thumbHeight != 1 && thumbWidth != 1 && pics . Count > 1 )
519528 {
520529 var fraction = new Fraction ( pics . Count , thumbHeight ) ;
521530 thumbWidth = ( int ) Math . Ceiling ( fraction . Decimal ) ;
522531 }
523532 }
524533
525- // Setup the grid layout
526- var exGrid = ExtendedGrid . ExtendGrid ( ThumbWidth , ThumbHeight , ThumbGrid ) ;
534+ // Update dependency properties so other code/XAML sees correct sizes
535+ ThumbWidth = thumbWidth ;
536+ ThumbHeight = thumbHeight ;
537+ ThumbCellSize = cellSize ;
527538
539+ // --- Setup grid layout ---
540+ var exGrid = ExtendedGrid . ExtendGrid ( thumbWidth , thumbHeight , thumbGrid ) ;
541+ Thb . Children . Clear ( ) ;
528542 _ = Thb . Children . Add ( exGrid ) ;
529543
530- var semaphore = new SemaphoreSlim ( 4 ) ; // limit concurrent image loads
544+ // --- Load images concurrently with semaphore ---
545+ var semaphore = new SemaphoreSlim ( 4 ) ;
531546 var tasks = pics . Select ( async kv =>
532547 {
533548 await semaphore . WaitAsync ( token ) ;
534549 try
535550 {
536- await LoadSingleImage ( kv . Key , kv . Value , exGrid , token ) ;
551+ await LoadSingleImage ( kv . Key , kv . Value , exGrid , token , cellSize , thumbWidth ) ;
537552 }
538553 finally
539554 {
@@ -543,29 +558,30 @@ private async Task LoadImages()
543558
544559 await Task . WhenAll ( tasks ) ;
545560
546- // Wait for all remaining tasks
547- await Task . WhenAll ( tasks ) ;
548-
549561 timer . Stop ( ) ;
550- Trace . WriteLine ( string . Concat ( ComCtlResources . DebugTimer , timer . Elapsed ) ) ;
562+ Trace . WriteLine ( $ " { ComCtlResources . DebugTimer } { timer . Elapsed } " ) ;
551563
552564 // Notify that loading is finished
553565 ImageLoaded ? . Invoke ( ) ;
554566 }
555567
556568 /// <summary>
557- /// Loads the image asynchronous.
569+ /// Loads the image asynchronous.
558570 /// </summary>
559571 /// <param name="key">The key.</param>
560572 /// <param name="filePath">The file path.</param>
561573 /// <param name="exGrid">The ex grid.</param>
562- /// <returns>Load all images async</returns>
563- private async Task LoadSingleImage ( int key , string filePath , Panel exGrid , CancellationToken token )
574+ /// <param name="token">The token.</param>
575+ /// <param name="cellSize">Size of the cell.</param>
576+ /// <param name="thumbWidth">Width of the thumb.</param>
577+ /// <returns>
578+ /// Load all images async
579+ /// </returns>
580+ private async Task LoadSingleImage ( int key , string filePath , Panel exGrid , CancellationToken token , int cellSize , int thumbWidth )
564581 {
565582 if ( token . IsCancellationRequested ) return ;
566583
567584 // Capture UI-thread values safely
568- int cellSize = await Application . Current . Dispatcher . InvokeAsync ( ( ) => ThumbCellSize ) ;
569585 bool isCheckBoxSelected = await Application . Current . Dispatcher . InvokeAsync ( ( ) => IsCheckBoxSelected ) ;
570586
571587 // Load the bitmap off the UI thread
@@ -620,14 +636,14 @@ await Application.Current.Dispatcher.InvokeAsync(() =>
620636 Border . TryAdd ( key , border ) ;
621637
622638 // Grid placement
623- Grid . SetRow ( border , key / ThumbWidth ) ;
624- Grid . SetColumn ( border , key % ThumbWidth ) ;
639+ Grid . SetRow ( border , key / thumbWidth ) ;
640+ Grid . SetColumn ( border , key % thumbWidth ) ;
625641 _ = exGrid . Children . Add ( border ) ;
626642
627643 if ( SelectBox && checkbox != null )
628644 {
629- Grid . SetRow ( checkbox , key / ThumbWidth ) ;
630- Grid . SetColumn ( checkbox , key % ThumbWidth ) ;
645+ Grid . SetRow ( checkbox , key / thumbWidth ) ;
646+ Grid . SetColumn ( checkbox , key % thumbWidth ) ;
631647 _ = exGrid . Children . Add ( checkbox ) ;
632648
633649 // Attach right-click event for context menu
0 commit comments