|
using DevExpress.XtraReports.UI; |
|
using DevExpress.XtraPrinting; |
|
using DevExpress.XtraEditors; |
|
|
|
public partial class MyReportViewerForm : XtraForm |
|
{ |
|
private XtraReport? _currentReport; |
|
private CancellationTokenSource? _cts; |
|
|
|
// Triggered by the Report's "Submit" button in the Parameters pane |
|
private async void OnReport_ParametersRequestSubmit(object? sender, DevExpress.XtraReports.Parameters.ParametersRequestEventArgs e) |
|
{ |
|
// 1. Thread Safety: Cancel any ongoing report generation |
|
_cts?.Cancel(); |
|
_cts = new CancellationTokenSource(); |
|
|
|
try |
|
{ |
|
// 2. Async Data Fetch (Generic Example) |
|
var reportData = await FetchReportDataAsync(e.Parameters, _cts.Token) |
|
.ConfigureAwait(ConfigureAwaitOptions.ContinueOnCapturedContext); |
|
|
|
// 3. Re-initialize and Bind |
|
await RefreshReportDisplayAsync(reportData, _cts.Token); |
|
} |
|
catch (OperationCanceledException) { /* Ignored */ } |
|
catch (Exception ex) |
|
{ |
|
XtraMessageBox.Show($"Error loading report: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); |
|
} |
|
} |
|
|
|
private async Task RefreshReportDisplayAsync(object? dataSource, CancellationToken ct) |
|
{ |
|
// Prevent memory leaks: Unsubscribe and Dispose old report instance |
|
if (_currentReport != null) |
|
{ |
|
_currentReport.ParametersRequestSubmit -= OnReport_ParametersRequestSubmit; |
|
_currentReport.Dispose(); |
|
} |
|
|
|
// Initialize your specific XtraReport class |
|
_currentReport = new MyXtraReport(); |
|
_currentReport.ParametersRequestSubmit += OnReport_ParametersRequestSubmit; |
|
|
|
// Assign fetched data |
|
_currentReport.DataSource = dataSource; |
|
|
|
// 4. Generate the document in the background |
|
await _currentReport.CreateDocumentAsync(ct).ConfigureAwait(ConfigureAwaitOptions.ContinueOnCapturedContext); |
|
|
|
// 5. Swap the PrintingSystem to refresh the DocumentViewer |
|
UpdateDocumentViewer(); |
|
} |
|
|
|
private void UpdateDocumentViewer() |
|
{ |
|
if (_currentReport == null) return; |
|
|
|
// We use ReportPrintTool to safely extract the PrintingSystem |
|
using ReportPrintTool tool = new(_currentReport); |
|
|
|
documentViewer1.PrintingSystem?.Dispose(); |
|
documentViewer1.PrintingSystem = tool.PrintingSystem; |
|
} |
|
|
|
private async Task<object?> FetchReportDataAsync(parameterCollection params, CancellationToken token) |
|
{ |
|
// Your DB logic here |
|
return await Task.FromResult<object?>(null); |
|
} |
|
} |