从另一个类访问的已填充ObservableCollection中没有任何项目

时间:2019-05-21 08:02:32

标签: c# windows uwp observablecollection autosuggest

我正在尝试访问一个已经在另一个类(viewModel)中填充的ObservableCollection。但是,它始终在ObservableCollection内部不返回任何内容。我需要这样做,以便可以对集合进行排序和搜索。有趣的是,当我将相同的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提交SearchQuerySubmit的代码:

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

非常感谢!!

2 个答案:

答案 0 :(得分:1)

在您的搜索查询提交方法中,您正在执行以下操作:

TasksViewModel viewModel = new TasksViewModel();

构造函数调用GetData,但是它返回一个Task,因为它没有返回类型,无法等待它,并且您甚至没有试图等待它返回要么完成。

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

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

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

但是请确保让GetData实际上返回某些内容,否则等待将不起作用,因为您无法等待返回void的异步方法。

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

答案 1 :(得分:0)

您不应在构造函数中开始异步操作。这是bad practice

构造函数返回时,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()方法的返回类型更改为Task,以便您可以等待它。除非是事件处理程序,否则async方法应返回TaskTask<T>。有关异步编程的最佳实践的更多信息,请参考@Stephen Cleary的MSDN Magazine article