When adding items to the ObservableCollection for my ItemSource, image not reflected in display

Hello, In my code I use an ObservableCollection<MyPictureClass> as the image source.
When I initially load the page, it reflects the images in the initial get from my database. However if the user adds an image to the database, and I re-build the ObservableCollection<MyPictureClass> the displayed Carousel doesn't reflect the new images, I have to exit the page, and return to it.

Here is my code.


/// <summary>
/// Says the cheese.
/// </summary>
internal void SayCheese(ref TemplateCarouselView control)
{
    try
    {
        RefreshPagePhotos();
        control.ItemsSource = lPhotos;
        OnPropertyChanged(nameof(lPhotos));
    }
    catch (Exception ex)
    {
        DebugTools.LogException(ex);
    }
    return;
}

//block the update until done with the Camera code. Then rebuild the image collection.
private async void RefreshPagePhotos() {     await CoreGlobals.dbSemaphore.WaitAsync();     await RefreshPhotos(); }

//Refresh the collection of images.
private
 async Task RefreshPhotos() {     if (MyWeapon.Id >= 0)     {         lPhotos = await PhotoRepo.GetItemByParentID(MyWeapon.Id, (int)RecordCatagory.Item, (int)RecordType.Type).ConfigureAwait(true);         OnPropertyChanged("lPhotos");     } }

My template for the carousel is pretty intense, so I've included it here (perhaps there's something here that's causing the problem?

public partial class TemplateCarouselView : SfCarousel
   {
       public DataTemplate dt;
 
       public TemplateCarouselView()
       {
           try
           {
               HeightRequest = 350;
               ItemHeight = 350;
               ItemSpacing = 2;
               ItemWidth = 250;
               ViewMode = ViewMode.Default;
               WidthRequest = 400;
               Offset = 1;
 
               dt = new DataTemplate(() =>
               {
                   var keyLayout = new StackLayout();
 
                   var bindPhoto = new Binding()
                   {
                       Converter = new FillImageFromBytes(),
                       Path = "Image"
                   };
 
                   var bindLocalPath = new Binding()
                   {
                       Converter = new FillImageFromBytes(),
                       Path = "."
                   };
 
                   var tgRec = new TapGestureRecognizer()
                   {
                       CommandParameter = bindLocalPath,
                       NumberOfTapsRequired = 1
                   };
 
                   tgRec.Tapped += async (s, e) =>
                   {
                       if (ActionList != null)
                       {
                           var act = await Application.Current.MainPage.DisplayActionSheet(
                                               StringTools.GetStringResource("szPhotoOptions"),
                                               null,
                                               StringTools.GetStringResource("szOK"),
                                               ActionList.ToArray());
                           await TapHandler.ImageTapHandler((Photos)((TappedEventArgs)e).Parameter, act, KeyButton, ParentObject);
                       }
                   };
 
                   //tgRec.SetBinding(TapGestureRecognizer.CommandProperty, bindTapped);
                   tgRec.SetBinding(TapGestureRecognizer.CommandParameterProperty, ".");
                   keyLayout.GestureRecognizers.Add(tgRec);
 
                   var img = new Image()
                   {
                       Aspect = Aspect.AspectFit,
                       HeightRequest = 350,
                       WidthRequest = 250,
                   };
                   img.SetBinding(Image.SourceProperty, bindPhoto);
                   var lblFileName = new Label()
                   {
                       HorizontalTextAlignment = TextAlignment.Center,
                   };
                   lblFileName.SetBinding(Label.TextProperty, "FileName");
                   keyLayout.Children.Add(img);
                   keyLayout.Children.Add(lblFileName);
 
                   return new ViewCell { View = keyLayout };
               });
           }
           catch (Exception ex)
           {
               DebugTools.LogException(ex);
           }
           ItemTemplate = dt;
       }
 
       /// <summary>
       /// The action list property
       /// </summary>
       public static readonly BindableProperty ActionListProperty = BindableProperty.Create(nameof(ActionList), typeof(List<string>), typeof(List<string>));
 
       /// <summary>
       /// Gets or sets the action list.
       /// </summary>
       /// <value>
       /// The action list.
       /// </value>
       public List<string> ActionList
       {
           get
           {
               return (List<string>)GetValue(ActionListProperty);
           }
 
           set
           {
               SetValue(ActionListProperty, value);
           }
       }
 
       /// <summary>
       /// The parent object property
       /// </summary>
       public static readonly BindableProperty ParentObjectProperty = BindableProperty.Create(nameof(ParentObject), typeof(Object), typeof(Object));
 
       /// <summary>
       /// Gets or sets the parent object.
       /// </summary>
       /// <value>
       /// The parent object.
       /// </value>
       public Object ParentObject
       {
           get
           {
               return (Object)GetValue(ParentObjectProperty);
           }
 
           set
           {
               SetValue(ParentObjectProperty, value);
           }
       }
 
       /// <summary>
       /// The key button property
       /// </summary>
       public static readonly BindableProperty KeyButtonProperty = BindableProperty.Create(nameof(KeyButton), typeof(ImageButton), typeof(ImageButton));
 
       /// <summary>
       /// Gets or sets the key button.
       /// </summary>
       /// <value>
       /// The key button.
       /// </value>
       public ImageButton KeyButton
       {
           get
           {
               return (ImageButton)GetValue(KeyButtonProperty);
           }
 
           set
           {
               SetValue(KeyButtonProperty, value);
           }
       }
   }

The additional bits I've added are for various controls that I link in to interfacing with this control.
When a user taps on an image there are a series of actions that are displayed for managing the images. There is also a "Key Image" that is an image button who's tap gesture recognizer initiates the camera function.

Since the Camera code is executing properly, and my semaphore process is functioning as expected (the camera code releases the semaphore when the image has been added to the database.)

I have tried this by just recreating the collection, by calling OnPropertyChanged("lPhotos"), and in this method, passing a pointer to the control, and reassigning the ItemSource with the new one.
How can I force the control to redraw it's self?

Cheers!

1 Reply

SP Sakthivel Palaniyappan Syncfusion Team February 23, 2021 10:39 AM UTC

Hi Jesse Knott,

Greetings from Syncfusion.

We have analyzed your query and checked the reported issue with by loading the images dynamically in simple sample as per your provided information, but we could not able to reproduce the reported issue. Sample we tried to reproduce the issue that can be download from  below.

Sample:
https://www.syncfusion.com/downloads/support/directtrac/general/ze/CarouselSample-659223213.zip

Since we are not aware of exact scenario of the issue, could you please check the issue with the attached sample and let us know whether it is reproduced or not? If the issue was not reproduced in this sample, please revert us by modifying the sample based on your application along with replication procedure or provide the sample. This will be helpful for us to investigate further and provide you a better solution at the earliest.

Regards,
Sakthivel P.
 


Loader.
Up arrow icon