我有问题。我为ViewModel
创建了这个CollectionView
:
public class TemplateListViewModel
{
public double WidthHeight { get; set; }
public ICommand LoadTemplates => new Command(MyHandler);
public int CurrentTemplateCountReceived;
public bool HitBottomOfList = false;
public ObservableCollection<TemplateSource> sourceList { get; set; }
public TemplateListViewModel()
{
CurrentTemplateCountReceived = 0;
sourceList = new ObservableCollection<TemplateSource>();
var mainDisplayInfo = DeviceDisplay.MainDisplayInfo;
var width = mainDisplayInfo.Width;
var density = mainDisplayInfo.Density;
var ScaledWidth = width / density;
WidthHeight = (ScaledWidth / 2);
loadingTemplates += onLoadingTemplates;
LoadTemplateList();
}
private event EventHandler loadingTemplates = delegate { };
private Task LoadTemplateList()
{
loadingTemplates(this, EventArgs.Empty);
return null;
}
private async void onLoadingTemplates(object sender, EventArgs args)
{
if (HitBottomOfList == false)
{
List<Template> templateList = await App.RestService.GetTemplates(App.User, CurrentTemplateCountReceived);
if (templateList != null)
{
foreach (var template in templateList)
{
ImageSource source = ImageSource.FromUri(new Uri("mysite.org/myapp/" + template.FileName));
TemplateSource templateSource = new TemplateSource { Id = template.Id, Source = source, WidthHeight = WidthHeight, FileName = template.FileName };
sourceList.Add(templateSource);
}
CurrentTemplateCountReceived = sourceList.Count;
}
else
{
HitBottomOfList = true;
}
}
}
bool handling = false;
public void MyHandler()
{
// already handling an event, ignore the new one
if (handling) return;
handling = true;
LoadTemplateList();
handling = false;
}
}
现在这是什么:它从我的网页收集图像位置,然后为这些收集的图像创建ImageSources
,并将其添加到sourceList。现在,我还在xaml中创建了一个RemainingItemsThresholdReachedCommand="{Binding LoadTemplates}"
,因此当它到达CollectionView
底部时,它会通过调用以下命令ICommand LoadTemplates => new Command(MyHandler);
来收集更多数据。此事件被触发了很多次,所以我创建了此处理程序:
public void MyHandler()
{
// already handling an event, ignore the new one
if (handling) return;
handling = true;
LoadTemplateList();
handling = false;
}
这将检查是否已经处理了一个事件。
问题在于,在MyHandler
中,LoadTemplateList()
没有等待结果,这导致对我的网页的许多调用,因为handling
将被设置为{{1} }!
现在如何等待false
?
答案 0 :(得分:1)
现在如何等待LoadTemplateList()?
使用await
关键字:
handling = true;
await LoadTemplateList();
handling = false;
但是,它仍然会提早返回,因为代码正在做一些时髦的私有EventHandler
东西。如果仅删除所有多余的代码并将异步代码移至LoadTemplateList
,它将可以正常工作:
public class TemplateListViewModel
{
public double WidthHeight { get; set; }
public ICommand LoadTemplates => new Command(MyHandler);
public int CurrentTemplateCountReceived;
public bool HitBottomOfList = false;
public ObservableCollection<TemplateSource> sourceList { get; set; }
public TemplateListViewModel()
{
CurrentTemplateCountReceived = 0;
sourceList = new ObservableCollection<TemplateSource>();
var mainDisplayInfo = DeviceDisplay.MainDisplayInfo;
var width = mainDisplayInfo.Width;
var density = mainDisplayInfo.Density;
var ScaledWidth = width / density;
WidthHeight = (ScaledWidth / 2);
MyHandler();
}
private async Task LoadTemplateList()
{
if (HitBottomOfList == false)
{
List<Template> templateList = await App.RestService.GetTemplates(App.User, CurrentTemplateCountReceived);
if (templateList != null)
{
foreach (var template in templateList)
{
ImageSource source = ImageSource.FromUri(new Uri("mysite.org/myapp/" + template.FileName));
TemplateSource templateSource = new TemplateSource { Id = template.Id, Source = source, WidthHeight = WidthHeight, FileName = template.FileName };
sourceList.Add(templateSource);
}
CurrentTemplateCountReceived = sourceList.Count;
}
else
{
HitBottomOfList = true;
}
}
}
bool handling = false;
public async void MyHandler()
{
// already handling an event, ignore the new one
if (handling) return;
handling = true;
await LoadTemplateList();
handling = false;
}
}
答案 1 :(得分:0)
您可能应该将Command
与CanExecute
和ChangeCanExecute
一起使用,如documentation
在订阅之前,-=
还取消订阅事件
您可以使命令异步,并添加等待的操作
Command MyCommand = new Command(async () => await ExecuteMyCommand());