Hello
Using following code i'm able to cancel getDocuments() method using standard wpf DataGrid and OperationCanceledException is thrown as expected.
When i'm using sfTreeGrid, CommandCancelLoadDocuments button on UserControl won't works, i can click it but cancelLoadDocuments is not raised.
I suppose sfTreeGrid, during its ItemsSource filling, restrain UI thread. However UI is not blocked, i can select Items and scroll the list but i can not stop the loading.
How can i solve the problem?
//UserControl XAML
<sf:SfTreeGrid ItemsSource="{Binding Collection.Documents}" AutoGenerateColumns="True"/>
<Button Command="{Binding CommandLoadDocuments}">Start Load</Button>
<Button Command="{Binding CommandCancelLoadDocuments}">Stop Load</Button>
//ViewModel
ViewModel()
{
Collection= new Collection();
}
//Action of CommandLoadDocuments
private void loadDocuments(object param)
{
if (Collection != null)
{
Task.Run(async () => await Collection.AsyncGetDocuments()).ConfigureAwait(false);
}
}
//Action of CommandCancelLoadDocuments
private void cancelLoadDocuments(object param)
{
if (Collection != null)
{
Collection.CancelLoadDocuments();
}
}
//Collection Class
public ObservableCollection<Tree> Documents { get; set; } = new ObservableCollection<BsonTree>();
public void CancelLoadDocuments()
{
cts.Cancel();
}
public async Task AsyncGetDocuments()
{
await Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
Documents.Clear();
progressHandler = new Progress<double>(value =>
{
LoadingDocProgress = Math.Round((decimal)value, 1);
});
}));
cts = new CancellationTokenSource();
var cancellationToken = cts.Token;
if (!cancellationToken.IsCancellationRequested)
{
try
{
getDocuments(cancellationToken);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
}
private readonly object _sync = new object();
private void getDocuments(CancellationToken token)
{
int i = 1;
var progress = progressHandler as IProgress<double>;
try
{
lock (_sync)
{
foreach (var item in sourceCollection.FindAll())
{
if (token.IsCancellationRequested)
{
Console.WriteLine("GetDocuments Cancelled");
token.ThrowIfCancellationRequested();
}
var doc = new Tree(item);
doc.GetNode();
Application.Current.Dispatcher.Invoke(() =>
{
Documents.Add(doc);
});
double x = 100 / Count * i;
progress.Report(x);
i++;
}
progress.Report(0);
}
}
catch(Exception ex)
{
if(ex.GetType() == typeof(OperationCanceledException))
{
Console.WriteLine(ex);
}
else
{
throw new Exception(ex.Message);
}
}
}