Description
Hello,
Rendering of Layouts are not updated if they contains controls (ContentView) with some rendering Task !
- I created a simple ContentView which contains three Image (the FireControl in the screenshot).
- In the constructor, I use a simple async method, with Task.Factory.StartNew, which will play on the visibility of the Face images with a small Task.Delay between them.
- In the MainPage, I load this control in a StackLayout, using a button : "Load control".
- It is impossible for me to add a second control (if I press again "Load control" )!
- It's like if the rendering of the StackLayout in my MainPage was not updated ...
- If I dont call my task method: no rendering problem!
- If I dont touch controls in my task method: no rendering problem !
- If I spam-click "Load control" and "Remove control", sometimes loaded controls appears...
Is there a way to tell my StackLayout to update its rendering after adding a control? Is there a better way than Task.Factory.StartNew to perform frame animation in a control, so as not to block the rendering? (In this example the desired animation has been simplified)
Steps to Reproduce
My Test solution : Test Solution
TestControl
public class TestControl : ContentView
{
protected Image FaceNormal;
protected Image FaceLoose;
public TestControl()
{
var principalImage = new Image { Source = "fire_principal.png" }; // The body
FaceNormal = new Image { Source = "fire_facenormal.png" }; // Opened eyes
FaceLoose = new Image { Source = "fire_faceloose.png" }; // Closed eyes
Content = new Grid { Children = { principalImage, FaceNormal, FaceLoose } }; // Loaded in the Content
// /!\ Causes rendering errors in the StackLayout
Task.Factory.StartNew(() => StartFaceAnimation());
}
public async Task StartFaceAnimation()
{
Dispatcher.Dispatch(() =>
{
FaceNormal.IsVisible = true;
FaceLoose.IsVisible = false;
});
await Task.Delay(2000);
Dispatcher.Dispatch(() =>
{
FaceNormal.IsVisible = false;
FaceLoose.IsVisible = true;
});
}
}
MainPage
public class MainPage : ContentPage
{
public MainPage()
{
var verticalStackLayout = new VerticalStackLayout();
var loadTestControlButton = new Button { Text = "Load control", Margin = 2 };
loadTestControlButton.Clicked += (o, e) => verticalStackLayout.Children.Add(new TestControl());
verticalStackLayout.Children.Add(loadTestControlButton);
var removeTestControlButton = new Button { Text = "Remove control", Margin = 2 };
removeTestControlButton.Clicked += (o, e) => verticalStackLayout.Children.Remove(verticalStackLayout.Children.Last());
verticalStackLayout.Children.Add(removeTestControlButton);
Content = verticalStackLayout;
}
}