我有一个使用MVVMLight的WPF项目,我需要显示来自OData服务(异步请求)的文章列表。
我想使用DataGridVirtualizingCollectionViewSource进行平滑滚动。
我的Xaml:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Platform"
<UserControl.Resources>
<xcdg:DataGridVirtualizingCollectionViewSource x:Key="Articles"
Source="{Binding Articles}"
PageSize="50"
ItemType="{x:Type types:Article}" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="QueryItems">
<cmd:EventToCommand Command="{Binding Path=QueryItemsCommand}" PassEventArgsToCommand="True" />
</i:EventTrigger>
<i:EventTrigger EventName="QueryItemCount">
<cmd:EventToCommand Command="{Binding Path=QueryItemCountCommand}" PassEventArgsToCommand="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
</xcdg:DataGridVirtualizingCollectionViewSource>
</UserControl.Resources>
<DockPanel LastChildFill="True" >
<xcdg:DataGridControl
x:Name="dataGrid"
ItemsSource="{Binding Source={StaticResource Articles}}"
>
<xcdg:DataGridControl.View>
<xcdg:TableflowView UseDefaultHeadersFooters="False">
<xcdg:TableflowView.FixedHeaders>
<DataTemplate>
<xcdg:ColumnManagerRow />
</DataTemplate>
</xcdg:TableflowView.FixedHeaders>
</xcdg:TableflowView>
</xcdg:DataGridControl.View>
</xcdg:DataGridControl>
</DockPanel>
我的ViewModel
public async Task QueryItems(QueryItemsEventArgs e)
{
var list = await myService.Articles.GetsAsync(top, e.AsyncQueryInfo.StartIndex);
e.AsyncQueryInfo.EndQuery(list.ToArray());
}
public async Task QueryItemCount(QueryItemCountEventArgs e)
{
e.Count = await myService.Articles.CountAsync();
}
private ICommand queryItemsCommand;
public ICommand QueryItemsCommand
{
get
{
return queryItemsCommand ?? (queryItemsCommand = new AsyncRelayCommand<QueryItemsEventArgs>(QueryItems));
}
}
private ICommand queryItemCountCommand;
public ICommand QueryItemCountCommand
{
get
{
return queryItemCountCommand ?? (queryItemCountCommand = new AsyncRelayCommand<QueryItemCountEventArgs>(QueryItemCount));
}
}
private ObservableCollection<Article> articles = new ObservableCollection<Article>();
public ObservableCollection<Article> Articles { get { return articles; } set { Set(ref articles, value); } }
AsyncRelayCommand.cs
public class AsyncRelayCommand<T> : ICommand
{
private readonly Func<T, Task> execute;
private readonly Func<T, bool> canExecute;
private long isExecuting;
public AsyncRelayCommand(Func<T, Task> execute, Func<T, bool> canExecute = null)
{
this.execute = execute;
this.canExecute = canExecute ?? (o => true);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void RaiseCanExecuteChanged()
{
CommandManager.InvalidateRequerySuggested();
}
public bool CanExecute(object parameter)
{
if (Interlocked.Read(ref isExecuting) != 0)
return false;
return canExecute((T)parameter);
}
public async void Execute(object parameter)
{
Interlocked.Exchange(ref isExecuting, 1);
RaiseCanExecuteChanged();
try
{
await execute((T)parameter);
}
finally
{
Interlocked.Exchange(ref isExecuting, 0);
RaiseCanExecuteChanged();
}
}
}
当我尝试此代码时,将正确触发QueryItemCount,e.Count异步获取计数,并且方法按预期完成。 但是在那之后,永远不会触发QueryItems!
当我强制刷新数据网格时,该计数被调用,但是该计数为-1,就像我从未设置过:(
我尝试了很多事情(Task.Run,.Result,UI线程上的调度等),但没有任何效果。 我需要一些新想法。 谢谢