У меня есть проект WPF с использованием MVVMLight, мне нужно показать список статей из службы OData (асинхронный запрос).
Я хочу использовать DataGridVirtualizingCollectionViewSource для плавной прокрутки.
My 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>
My 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, Dispatch в потоке пользовательского интерфейса и т. Д.), Но ничего не получается. Мне нужны новые идеи .... Спасибо