簡體   English   中英

屬性更改未在任務內觸發

[英]Property changed is not being triggered inside a Task

我有一個簡單的應用程序,當某些任務正在運行時,我會顯示進度環,並在完成后立即隱藏進度環。 這段代碼的問題是進度條永遠不會折疊。 我在值轉換器 class 中保留了一個斷點,即使在值更改后它也不會收到 false 值。 因此,ProgressRing 永遠不會崩潰。 請幫忙。

這是我的視圖模型

public class TestVM : INotifyPropertyChanged
    {
        private bool _isRingVisible;
        public bool IsRingVisible
        {
            get => _isRingVisible;
            set
            {
                _isRingVisible = value;
                OnPropertyChanged(nameof(IsRingVisible));
            }
        }
        public TestVM()
        {
            Task.Run(async () => await DoSomething());
        }

        private async Task DoSomething()
        {
            IsRingVisible = true;
            await Task.Delay(5000);
            IsRingVisible = false; //Value set to false but when I have a break point in the value converter class, it never receives this value.
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

在 xaml 我有一個簡單的用戶界面如下,

<Page.Resources>
        <converter:BoolToVisibilityConverter x:Key="boolToVisibility"/>
    </Page.Resources>
<Grid>
        <Border x:Name="BdrProgressRing" 
                    Grid.Row="0" 
                    Grid.RowSpan="2" 
                    Background="Red"
                    VerticalAlignment="Center"
                    Opacity="0.6" 
                    Visibility="{x:Bind vm.IsRingVisible,Mode=OneWay,Converter={StaticResource boolToVisibility}}">
        </Border>
        <ProgressRing x:Name="PgRing" 
                          Grid.Row="0" 
                          Grid.RowSpan="2"
                          Visibility="{Binding ElementName=BdrProgressRing, Path=Visibility}"
                          IsActive="True"  
                          VerticalAlignment="Center"
                          Width="90"
                          Height="90"/>
    </Grid>

這是我的 xaml.cs

public sealed partial class MainPage : Page
    {
        public TestVM vm { get; set; }
        public MainPage()
        {
            this.InitializeComponent();
            vm = new TestVM();
            this.DataContext = this;
        }
    }

改變

Task.Run(async () => await DoSomething()) ;

_ = DoSomething();

可能您只允許從 Main UI Thread 更改屬性,而不是從 pooled Task更改。 在 WPF 中了解有關同步上下文的更多信息。


但是,以上是不好的做法。 應該等待任何異步方法。 簡單地將DoSomething()返回的 Task 分配給局部變量是不夠的。

由於您不能在構造函數中等待,因此視圖 model 應該有一個由調用者實際等待的公共等待方法,例如

public TestVM()
{
}

public Task Initialize()
{
    return DoSomething();
}

然后調用await vm.Initialize(); 在視圖中的異步加載事件處理程序中:

public MainPage()
{
    InitializeComponent();
    vm = new TestVM();
    DataContext = this;

    Loaded += async (s, e) => await vm.Initialize();
}

暫無
暫無

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

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