locked
BindableProperty of ImageSource type raises PropertyChanged twice in custom Views RRS feed

  • Question

  • User2773 posted

    In custom views, when using ImageSource bindable properties, the PropertyChanged is raised twice! It can lead to major performance issues in custom controls using images.

    Output: !!! HomeViewModel PropertyChanged: ShowImage, value: http://ed66d424bbb74367b326a5d9900185c4.com !!! View PropertyChanged: Image, Image hash: 289996192, value: http://ed66d424bbb74367b326a5d9900185c4.com/ !!! View PropertyChanged: Image, Image hash: 671983716, value: http://ed66d424bbb74367b326a5d9900185c4.com/

    Is it a bug? Or am I missing something?

    Code:

    public class App : Application
    {
      public App()
      {
        var viewModel = new HomeViewModel();
    
        var myView = new MyView();
        myView.SetBinding<HomeViewModel>(MyView.ImageProperty, v => v.ShowImage);
    
        MainPage = new ContentPage {
          BindingContext = viewModel,
          Content = myView 
        };
    
        viewModel.Reload();
      }
    
      public class MyView : View
      {
        public MyView()
        {
          PropertyChanged += (sender, e) => {
            if (e.PropertyName == MyView.ImageProperty.PropertyName)
              Console.WriteLine(string.Format("!!! View PropertyChanged: {0}, Image hash: {1}, value: {2}", 
                e.PropertyName, Image.GetHashCode(), ((UriImageSource)Image).Uri));
          };
        }
    
        public static readonly BindableProperty ImageProperty = BindableProperty.Create<MyView, ImageSource>(w => w.Image, null);
    
        public ImageSource Image
        {
          get
          {
            return (ImageSource)GetValue(ImageProperty);
          }
          set
          {
            SetValue(ImageProperty, value);
          }
        }
      }
    
      public class HomeViewModel : INotifyPropertyChanged
      {
        public HomeViewModel()
        {
          PropertyChanged += (sender, e) => {
            if (e.PropertyName == "ShowImage")
              Console.WriteLine(string.Format("!!! HomeViewModel PropertyChanged: {0}, value: {1}", 
                e.PropertyName, ShowImage));
          };
        }
    
        public void Reload()
        {
          ShowImage = "http://" + Guid.NewGuid().ToString("N") + ".com";
        }
    
        string showImage;
        public string ShowImage
        {
          get
          {
            return showImage;
          }
          set
          {
            showImage = value;
            OnPropertyChanged("ShowImage");
          }
        }
    
        #region INotifyPropertyChanged implementation
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        #endregion
    
        public void OnPropertyChanged(string propertyName)
        {
          PropertyChangedEventHandler handler = PropertyChanged;
          if (handler != null) 
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
      }
    
      protected override void OnStart()
      {
        // Handle when your app starts
      }
    
      protected override void OnSleep()
      {
        // Handle when your app sleeps
      }
    
      protected override void OnResume()
      {
        // Handle when your app resumes
      }
    }
    
    Friday, October 2, 2015 2:53 AM

Answers

  • User158279 posted

    I've actually been noticing that for the last couple weeks. Just thought it was an idiosyncrasy of Xamarin. Its not just ImageSource. I just had it on a sample I was writing up for automatically switching a SwitchCell on and off. Had it earlier today when I was working on binding a convertor to a collection. In fact I can't remember it NOT happening twice if I explicitly call it but then I haven't been paying close attention.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Friday, October 2, 2015 5:02 PM
  • User15966 posted

    People having this issue can complain about it in this Xamarin bugzilla: https://bugzilla.xamarin.com/show_bug.cgi?id=34531

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Saturday, October 3, 2015 8:47 AM

All replies

  • User2773 posted

    Anyone?

    Friday, October 2, 2015 4:26 PM
  • User158279 posted

    I've actually been noticing that for the last couple weeks. Just thought it was an idiosyncrasy of Xamarin. Its not just ImageSource. I just had it on a sample I was writing up for automatically switching a SwitchCell on and off. Had it earlier today when I was working on binding a convertor to a collection. In fact I can't remember it NOT happening twice if I explicitly call it but then I haven't been paying close attention.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Friday, October 2, 2015 5:02 PM
  • User2773 posted

    @DavidStrickland0 Thanks for the info! I'm not alone! :) In my opinion, it should be filled as a bug or at least documented somewhere. On some simple things, performance hit is negligible. But ImageSource is mostly used with images. Redrawing something twice can lead to visible UI slowness and memory usage problems.

    Friday, October 2, 2015 5:17 PM
  • User15966 posted

    People having this issue can complain about it in this Xamarin bugzilla: https://bugzilla.xamarin.com/show_bug.cgi?id=34531

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Saturday, October 3, 2015 8:47 AM
  • User51749 posted

    I'm getting this problem with the latest version of Xamarin Forms (just updated)

    Sunday, December 20, 2015 1:21 PM