我正在尝试访问一个已经在另一个类(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);
}
}
非常感谢!!
答案 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
方法应返回Task
或Task<T>
。有关异步编程的最佳实践的更多信息,请参考@Stephen Cleary的MSDN Magazine article。