如果在异步调用后设置,UWP中的布尔值未在UI中更新

3

我在我的UWP应用中有一个公共的布尔变量,用于显示/隐藏ProgressBar。我在其他地方使用了相同的模式,看起来工作得不错,但是在特定页面上遇到了一个问题,当我在异步调用之后设置布尔值时,它似乎不会在UI中更新(与正常工作的页面相同)。

以下是我的XAML视图:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <TextBlock Text="{ x:Bind Vm.IsLoaded }" Margin="112,272,-112,-272"></TextBlock>
</Grid>

对应的代码文件:

public sealed partial class MainPage : Page
{
    public MainPageViewModel Vm => DataContext as MainPageViewModel;
    public MainPage()
    {
        this.InitializeComponent();
        this.DataContext = new MainPageViewModel();
    }

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);

        Vm.GetProjectData();
    }
}

以下是我的MainPageViewModel.cs文件

public class MainPageViewModel : ViewModel
{
    public ObservableCollection<Project> Projects { get; set; } = new ObservableCollection<Project>();

    private bool _isLoaded;
    public bool IsLoaded
    {
        get { return _isLoaded; }
        set
        {
            _isLoaded = value;
            OnPropertyChanged();
        }
    }

    public async Task GetProjectData()
    {
        // If I put `IsLoaded = true;` here it displays `true` in the UI
        var projectsResponse = await HttpUtil.GetAsync(StringUtil.ProjectsUrl());
        // If I put `IsLoaded = true;` here it still displays `false` in the UI
        if (projectsResponse.IsSuccessStatusCode)
        {
            var projectsResponseString = await projectsResponse.Content.ReadAsStringAsync();
            var projects = JsonUtil.SerializeJsonToObject<List<Project>>(projectsResponseString);

            foreach (var project in projects)
            {
                Projects.Add(project);
            }

            IsLoaded = true;
       }
    }
}

我的ViewModel.cs文件:
public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

无论我把 IsLoaded = true; 放在哪里,它总会触发 OnPropertyChanged()。
下面是我的可用代码:
ProjectViewViewModel.cs:
public class ProjectViewViewModel : ViewModel
{
    public ObservableCollection<Story> MyData { get; set; } = new ObservableCollection<Story>();
    private bool _dataIsLoaded;
    public bool DataIsLoaded
    {
        get { return _dataIsLoaded; }
        set
        {
            _dataIsLoaded = value;
            OnPropertyChanged();
        }
    }

    public async Task GetData(Project project)
    {
        DataIsLoaded = false;
        var stringResponse = await HttpUtil.GetAsync(StringUtil.Query(project.Id, "MB"));
        if (stringResponse.IsSuccessStatusCode)
        {
            // Do Stuff

            DataIsLoaded = true;
        }
    }
}

ProjectView.xaml.cs

public sealed partial class ProjectView : Page
{
    public Project Project { get; set; }
    public bool IsLoaded { get; set; }
    public ProjectViewViewModel Vm => DataContext as ProjectViewViewModel;
    public ProjectView()
    {
        this.InitializeComponent();
        this.DataContext = new ProjectViewViewModel();
    }

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);

        Project = e.Parameter as Project;
        Vm.GetData(Project);
    }
}

我感觉自己可能忽略了非常明显的一些问题,但是却无法看到树林中的大树而感到烦恼。非常感谢任何帮助!

1个回答

6

我相信你遇到的问题在于你的标记。x:Bind的默认绑定模式是OneTime; 因此,文本块中的文本绑定到IsLoaded的值,在应用程序启动时或当文本块的数据上下文发生更改时。将绑定模式设置为OneWay应该会导致文本块中的值在异步函数返回后更新。

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <TextBlock Text="{ x:Bind Path=Vm.IsLoaded, Mode=OneWay }" Margin="112,272,-112,-272"></TextBlock>
</Grid>

如果您感兴趣,这篇文章详细介绍了x:Bind的使用。此外,这篇文章涵盖了BindingMode枚举中的值。

那绝对是问题所在!那个讨厌的绑定模式! - Matt Brewerton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接