diff --git a/src/SamplesApp/UITests.Shared/UITests.Shared.projitems b/src/SamplesApp/UITests.Shared/UITests.Shared.projitems index d9bb1b4d2c44..8195fb07a00d 100644 --- a/src/SamplesApp/UITests.Shared/UITests.Shared.projitems +++ b/src/SamplesApp/UITests.Shared/UITests.Shared.projitems @@ -2378,6 +2378,10 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + Designer MSBuild:Compile @@ -7182,6 +7186,9 @@ PersonPicturePage.xaml + + PersonPictureLateBindingPage.xaml + Pivot_CustomContent_Automated.xaml diff --git a/src/SamplesApp/UITests.Shared/Windows_UI_Xaml_Controls/PersonPictureTests/PersonPictureLateBindingPage.xaml b/src/SamplesApp/UITests.Shared/Windows_UI_Xaml_Controls/PersonPictureTests/PersonPictureLateBindingPage.xaml new file mode 100644 index 000000000000..f9cabbb1bb51 --- /dev/null +++ b/src/SamplesApp/UITests.Shared/Windows_UI_Xaml_Controls/PersonPictureTests/PersonPictureLateBindingPage.xaml @@ -0,0 +1,27 @@ + + + + + + + + + + diff --git a/src/SamplesApp/UITests.Shared/Windows_UI_Xaml_Controls/PersonPictureTests/PersonPictureLateBindingPage.xaml.cs b/src/SamplesApp/UITests.Shared/Windows_UI_Xaml_Controls/PersonPictureTests/PersonPictureLateBindingPage.xaml.cs new file mode 100644 index 000000000000..cccf100a02d5 --- /dev/null +++ b/src/SamplesApp/UITests.Shared/Windows_UI_Xaml_Controls/PersonPictureTests/PersonPictureLateBindingPage.xaml.cs @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +using System; +using System.Collections.ObjectModel; +using MUXControlsTestApp.Utilities; +using Uno.UI.Samples.Controls; +using Windows.ApplicationModel.Contacts; +using System.Threading.Tasks; + +namespace MUXControlsTestApp +{ + [SampleControlInfo( + "MUX", + "PersonPictureLateBinding", + description: "Shows a PersonPicture control and a Textblock with a name. \n" + + "The PersonPicture control image is set after 1 second delay. \n" + + "The image should be displayed after the delay.", + isManualTest: true)] +#pragma warning disable UXAML0002 // does not explicitly define the Microsoft.UI.Xaml.Controls.UserControl base type in code behind. + public sealed partial class PersonPictureLateBindingPage +#pragma warning restore UXAML0002 // does not explicitly define the Microsoft.UI.Xaml.Controls.UserControl base type in code behind. + { + public string ImagePath { get; } = "ms-appx:///Assets/ingredient2.png"; + + public string LeName { get; } = "James Bondi"; + + public PersonPictureLateBindingPage() + { + this.InitializeComponent(); + _ = SetImagePathWithDelay(); + } + + private async Task SetImagePathWithDelay() + { + await Task.Delay(1000); + DataContext = this; + } + } +} diff --git a/src/Uno.UI/Microsoft/UI/Xaml/Controls/PersonPicture/PersonPicture.cs b/src/Uno.UI/Microsoft/UI/Xaml/Controls/PersonPicture/PersonPicture.cs index 0d7fd206d9d0..9fd98701201b 100644 --- a/src/Uno.UI/Microsoft/UI/Xaml/Controls/PersonPicture/PersonPicture.cs +++ b/src/Uno.UI/Microsoft/UI/Xaml/Controls/PersonPicture/PersonPicture.cs @@ -203,23 +203,33 @@ void UpdateIfReady() var templateSettings = TemplateSettings; templateSettings.ActualInitials = initials; - if (imageSrc != null) + + if (imageSrc is not null) { - var imageBrush = templateSettings.ActualImageBrush; - if (imageBrush == null) + if (templateSettings.ActualImageBrush is ImageBrush imageBrush) { - imageBrush = new ImageBrush(); - imageBrush.Stretch = Stretch.UniformToFill; - templateSettings.ActualImageBrush = imageBrush; + imageBrush.ImageSource = imageSrc; + } + else + { + templateSettings.ActualImageBrush = new ImageBrush() + { + ImageSource = imageSrc, + Stretch = Stretch.UniformToFill + }; } - - imageBrush.ImageSource = imageSrc; } else { templateSettings.ActualImageBrush = null; } +#if __IOS__ + if (templateSettings.ActualImageBrush is ImageBrush brush) + { + brush.ImageOpened += RefreshPhoto; + } +#endif // If the control is converted to 'Group-mode', we'll clear individual-specific information. // When IsGroup evaluates to false, we will restore state. if (IsGroup) @@ -228,7 +238,11 @@ void UpdateIfReady() } else { - if (imageSrc != null) + if (imageSrc is not null +#if __IOS__ + && imageSrc.IsOpened +#endif + ) { VisualStateManager.GoToState(this, "Photo", false); } @@ -245,6 +259,18 @@ void UpdateIfReady() UpdateAutomationName(); } +#if __IOS__ + void RefreshPhoto(object sender, RoutedEventArgs e) + { + VisualStateManager.GoToState(this, "Photo", false); + + if (TemplateSettings.ActualImageBrush is { } brush) + { + brush.ImageOpened -= RefreshPhoto; + } + } +#endif + void UpdateBadge() { if (BadgeImageSource != null) diff --git a/src/Uno.UI/UI/Xaml/Media/ImageSource.iOS.cs b/src/Uno.UI/UI/Xaml/Media/ImageSource.iOS.cs index 31926877edaf..a94258af0251 100644 --- a/src/Uno.UI/UI/Xaml/Media/ImageSource.iOS.cs +++ b/src/Uno.UI/UI/Xaml/Media/ImageSource.iOS.cs @@ -55,6 +55,11 @@ public static NSUrlSession DefaultSession static public implicit operator ImageSource(UIImage image) => new ImageSource(image); + /// + /// Indicates that this source has already been opened (So TryOpenSync will return true!) + /// + internal bool IsOpened => _imageData.HasData; + private static UIImage? OpenBundleFromString(string? bundle) { if (!bundle.IsNullOrWhiteSpace())