簡體   English   中英

使用任務修改控件時布局呈現錯誤

[英]Layout render error when using Tasks modifying controls

描述

你好,

如果布局包含帶有一些渲染任務的控件(ContentView),則不會更新布局的渲染!

  1. 我創建了一個簡單的 ContentView,其中包含三個 Image(屏幕截圖中的 FireControl)。
  2. 在構造函數中,我使用了一個簡單的異步方法,帶有 Task.Factory.StartNew,它將在人臉圖像的可見性上播放,它們之間有一個小的 Task.Delay。
  3. 在 MainPage 中,我使用一個按鈕將這個控件加載到 StackLayout 中:“加載控件”。
  • 我不可能添加第二個控件(如果我再次按下“加載控件”)!
  • 就像我的 MainPage 中 StackLayout 的渲染沒有更新一樣......
  • 如果我不調用我的任務方法:沒有渲染問題!
  • 如果我在我的任務方法中不觸摸控件:沒有渲染問題!
  • 如果我垃圾郵件單擊“加載控件”和“刪除控件”,有時會出現加載的控件...

有沒有辦法告訴我的 StackLayout 在添加控件后更新其渲染? 有沒有比 Task.Factory.StartNew 更好的方法在控件中執行幀動畫,以免阻塞渲染? (在此示例中,所需的動畫已被簡化)

重現步驟

我的測試解決方案: 測試解決方案

測控

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

主頁

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

訣竅是在 IsVisible 之后調用 Arrange,請參閱以下修改:

public async Task StartFaceAnimation()
    {
        Dispatcher.Dispatch(() =>
        {
            FaceNormal.IsVisible = true;
            FaceLoose.IsVisible = false;
            Arrange(new Rect());
        });
        await Task.Delay(2000);
        Dispatcher.Dispatch(() =>
        {
            FaceNormal.IsVisible = false;
            FaceLoose.IsVisible = true;
            Arrange(new Rect());
        });
    }

它重繪控件!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM