首页 > 解决方案 > 从异步方法更新标签/文本块

问题描述

我在尝试更新我的 UI 时遇到了一个奇怪的问题。我IProgress用来报告我的异步方法的状态,然后应该更新我视图中的标签。发生的事情是异步方法运行并且标签仅在异步方法完成时更新。我希望标签在异步方法运行时多次更新。

在测试时,我注意到如果我使用窗口的 Title 属性而不是我的标签来显示异步方法的进度,那么它会完全按预期工作。我通过将LblLoading属性绑定到我的视图的标题来做到这一点。只有在异步方法运行时更新标签或文本块才会出现问题。谁能解释为什么会发生这种情况以及我如何解决它?

我正在使用 MVVM 和 Prism。异步工作通过按下运行的按钮开始InitStartup()。这是我完成所有异步工作的工人类:

public class Worker
{
    private string _status;

    public async Task DoWork(IProgress<string> progress)
    {
        for (int i = 0; i < 10000; i++)
        {
            Status = "Test" + i;
            progress.Report(Status);
        }
    }
}

查看型号:

public class MainWindowViewModel : BindableBase
{
    public MainWindowViewModel()
    {
        StartCommand = new DelegateCommand(InitStartup);
    }

    public DelegateCommand StartCommand { get; set; }

    private string _lblLoading = "TEST"; 
    public string LblLoading
    {
        get { return _lblLoading; }
        set { SetProperty(ref _lblLoading, value); }
    }

    private void InitStartup()
    {
        Progress<string> progress = new Progress<string>();
        progress.ProgressChanged += UpdateProgress;

        var startup = new Worker();

        Task.Run(() => startup.DoWork(progress));
    }

    private void UpdateProgress(object sender, string status)
    {
        LblLoading = status;
    }
}

看法:

<Window x:Class="AsyncProgressTest.Views.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:prism="http://prismlibrary.com/"
    prism:ViewModelLocator.AutoWireViewModel="True"
    Title="{Binding LblLoading}" Height="350" Width="525">
<Grid>
    <ContentControl prism:RegionManager.RegionName="ContentRegion" />
    <StackPanel>
        <Label Content="{Binding LblLoading}"/>
        <Button Content="Start" Command="{Binding StartCommand}"/>
    </StackPanel>
</Grid>

标签: c#wpfasynchronousmvvmprism

解决方案


1)我认为它应该是这样的:

public class Worker
{
    public string Status { get; set; }

    public async Task DoWork(IProgress<string> progress)
    {
        for (int i = 0; i < 10000; i++)
        {
            Status = "Test" + i;
            progress.Report(Status);
            await Task.Delay(100);
        }
    }
}

2)您应该确保您的 MainWindowViewModel 已创建。我不明白你试图在这段代码中做什么,但是通过修复,这段代码可以正常工作。

您的问题出在您的 DoWork 方法中。这是同步完成的。


推荐阅读