从另一个 class 访问时填充的 ObservableCollection 中没有项目

No Items in Populated ObservableCollection when accessed from another class

我正在尝试访问已经填充到另一个 class(viewModel)中的 ObservableCollection。但是,ObservableCollection 中始终 returns 没有任何内容。我需要这个以便可以对集合进行排序和搜索。有趣的是,当我将同一个 ObservableCollection 加载到 AutoSuggestBox 中时,它会显示 ObservableCollection 中的项目...

集合排序代码:

protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        Frame currentFrame = Window.Current.Content as Frame;
        MainPage mainPage = currentFrame.Content as MainPage;
        mainPage.UpdateNavigationView(0);

        TasksViewModel viewModel = new TasksViewModel();
        int count = viewModel.searchableTaskTitles.Count();
        bool swapped = false;

        while (swapped == false)
        {
            swapped = true;
            int loopCount = 0;
            System.Diagnostics.Debug.WriteLine(count);
            while (loopCount + 1 != count + 1)
            {
                if (string.Compare(viewModel.searchableTaskTitles.ElementAt(loopCount), viewModel.searchableTaskTitles.ElementAt(loopCount + 1)) == 1)
                {
                    string a = viewModel.searchableTaskTitles[loopCount];
                    viewModel.searchableTaskTitles[loopCount] = viewModel.searchableTaskTitles[loopCount + 1];
                    viewModel.searchableTaskTitles[loopCount + 1] = a;
                    swapped = false;
                }
                loopCount = loopCount + 1;
            }
            loopCount = 0;
        }
    }

获取数据的代码:

public class TasksViewModel
    {

        public System.Collections.ObjectModel.ObservableCollection<string> searchableTaskTitles = new System.Collections.ObjectModel.ObservableCollection<string>();
        public List<string> taskTitles = new List<string>();

        public async void GetData()
        {
            string taskTitle;
            string taskImportance;
            string taskCompletion;
            string taskDesc;
            StorageFolder folder = await ApplicationData.Current.LocalFolder.CreateFolderAsync("Tasks", CreationCollisionOption.OpenIfExists);
            IReadOnlyCollection<StorageFile> fileNames = await folder.GetFilesAsync();

            foreach (StorageFile file in fileNames)
            {
                using (var inputStream = await file.OpenReadAsync())
                using (var classicStream = inputStream.AsStreamForRead())
                using (var streamReader = new StreamReader(classicStream))
                {
                    taskTitle = string.Format(streamReader.ReadLine());
                    taskImportance = string.Format(streamReader.ReadLine());
                    taskCompletion = string.Format(streamReader.ReadLine()) + "%";
                    taskDesc = string.Format(streamReader.ReadToEnd());
                }

                this.searchableTaskTitles.Add(taskTitle);

                this.taskTitles.Add(taskTitle);
            }
        }

        public TasksViewModel()
        {
            GetData();
        }
    }

以防万一...AutoSuggestBox 的 SearchQuerySubmitted 代码:

private void SearchQuerySubmitted(AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
        {
            if (args.ChosenSuggestion != null)
            {
                SearchAutoSuggestBox.Text = args.ChosenSuggestion.ToString();
                string searchText = args.ChosenSuggestion.ToString();

                int clickedItem = 0;
                TasksViewModel viewModel = new TasksViewModel();
                foreach (string item in viewModel.taskTitles)
                {
                    if (searchText == item)
                    {
                        clickedItem = viewModel.taskTitles.IndexOf(item);
                    }
                }
                System.Diagnostics.Debug.WriteLine(clickedItem);
                this.Frame.Navigate(typeof(ViewTaskPage), clickedItem);
            }
        }

非常感谢!!!

在您的搜索查询提交方法中,您这样做:

TasksViewModel viewModel = new TasksViewModel();

构造函数调用 GetData 但是这个 return 是一个 Task 因为它没有 return 类型,所以不能等待它,你甚至都没有尝试等待它完成。

您需要放弃异步,或者 return 一个值并在构造函数中等待它。

无论如何你都不应该在构造函数中进行异步工作,所以我的建议是将这段代码更改为:

TasksViewModel viewModel = new TasksViewModel();
await viewModel.GetData();

但是一定要 GetData 实际上 return 一些东西,否则等待将不起作用,因为你不能等待 void-returning 异步方法。

有关如何正确使用异步/等待的更多信息,请参阅MSDN

您不应在构造函数中启动异步操作。这是一个bad practice

构造函数return时GetData()方法仍然是运行。您可以从 OnNavigatedTo 方法中调用它,而不是在构造函数中调用它:

protected override async void OnNavigatedTo(NavigationEventArgs e)
{
    Frame currentFrame = Window.Current.Content as Frame;
    MainPage mainPage = currentFrame.Content as MainPage;
    mainPage.UpdateNavigationView(0);

    TasksViewModel viewModel = new TasksViewModel();
    await viewModel.GetData();
    int count = viewModel.searchableTaskTitles.Count();
    bool swapped = false;

    while (swapped == false)
    {
        swapped = true;
        int loopCount = 0;
        System.Diagnostics.Debug.WriteLine(count);
        while (loopCount + 1 != count + 1)
        {
            if (string.Compare(viewModel.searchableTaskTitles.ElementAt(loopCount), viewModel.searchableTaskTitles.ElementAt(loopCount + 1)) == 1)
            {
                string a = viewModel.searchableTaskTitles[loopCount];
                viewModel.searchableTaskTitles[loopCount] = viewModel.searchableTaskTitles[loopCount + 1];
                viewModel.searchableTaskTitles[loopCount + 1] = a;
                swapped = false;
            }
            loopCount = loopCount + 1;
        }
        loopCount = 0;
    }
}

您还应该将 GetData() 方法的 return 类型更改为 Task 以便您能够等待它。 async 方法应该 return TaskTask<T> 除非它是事件处理程序。请参阅@Stephen Cleary 的 MSDN Magazine article 以获取有关异步编程最佳实践的更多信息。