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
}
}