从另一个 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 Task
或 Task<T>
除非它是事件处理程序。请参阅@Stephen Cleary 的 MSDN Magazine article 以获取有关异步编程最佳实践的更多信息。
我正在尝试访问已经填充到另一个 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 Task
或 Task<T>
除非它是事件处理程序。请参阅@Stephen Cleary 的 MSDN Magazine article 以获取有关异步编程最佳实践的更多信息。