diff --git a/XLAB2/App.xaml.cs b/XLAB2/App.xaml.cs
index 4da3e08..1d78001 100644
--- a/XLAB2/App.xaml.cs
+++ b/XLAB2/App.xaml.cs
@@ -4,6 +4,7 @@ using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Markup;
+using System.Windows.Threading;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using XLAB2.Infrastructure;
@@ -17,6 +18,7 @@ namespace XLAB2
public App()
{
ApplyRussianCulture();
+ RegisterGlobalExceptionHandlers();
}
protected override async void OnStartup(StartupEventArgs e)
@@ -40,19 +42,29 @@ namespace XLAB2
protected override async void OnExit(ExitEventArgs e)
{
- if (_host != null)
+ try
{
- try
+ if (_host != null)
{
- await _host.StopAsync(TimeSpan.FromSeconds(5)).ConfigureAwait(true);
- }
- finally
- {
- _host.Dispose();
+ try
+ {
+ await _host.StopAsync(TimeSpan.FromSeconds(5)).ConfigureAwait(true);
+ }
+ finally
+ {
+ _host.Dispose();
+ }
}
}
-
- base.OnExit(e);
+ catch (Exception ex)
+ {
+ ShowUnhandledException(ex, true);
+ }
+ finally
+ {
+ UnregisterGlobalExceptionHandlers();
+ base.OnExit(e);
+ }
}
private static void ApplyRussianCulture()
@@ -68,5 +80,77 @@ namespace XLAB2
typeof(FrameworkElement),
new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(culture.IetfLanguageTag)));
}
+
+ private void RegisterGlobalExceptionHandlers()
+ {
+ DispatcherUnhandledException += OnDispatcherUnhandledException;
+ AppDomain.CurrentDomain.UnhandledException += OnCurrentDomainUnhandledException;
+ TaskScheduler.UnobservedTaskException += OnUnobservedTaskException;
+ }
+
+ private void UnregisterGlobalExceptionHandlers()
+ {
+ DispatcherUnhandledException -= OnDispatcherUnhandledException;
+ AppDomain.CurrentDomain.UnhandledException -= OnCurrentDomainUnhandledException;
+ TaskScheduler.UnobservedTaskException -= OnUnobservedTaskException;
+ }
+
+ private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
+ {
+ ShowUnhandledException(e.Exception, false);
+ e.Handled = true;
+ }
+
+ private void OnCurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
+ {
+ var exception = e.ExceptionObject as Exception;
+ if (exception != null)
+ {
+ ShowUnhandledException(exception, e.IsTerminating);
+ return;
+ }
+
+ MessageBox.Show(
+ e.ExceptionObject == null ? "Произошла необработанная ошибка." : e.ExceptionObject.ToString(),
+ e.IsTerminating ? "XLAB2 - критическая ошибка" : "XLAB2",
+ MessageBoxButton.OK,
+ MessageBoxImage.Error);
+ }
+
+ private void OnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
+ {
+ ShowUnhandledException(e.Exception, false);
+ e.SetObserved();
+ }
+
+ private static void ShowUnhandledException(Exception exception, bool isCritical)
+ {
+ var actualException = UnwrapException(exception);
+ var message = string.IsNullOrWhiteSpace(actualException.Message)
+ ? actualException.ToString()
+ : actualException.Message;
+
+ MessageBox.Show(
+ message,
+ isCritical ? "XLAB2 - критическая ошибка" : "XLAB2",
+ MessageBoxButton.OK,
+ MessageBoxImage.Error);
+ }
+
+ private static Exception UnwrapException(Exception exception)
+ {
+ if (exception is AggregateException aggregateException)
+ {
+ var flattened = aggregateException.Flatten();
+ if (flattened.InnerExceptions.Count == 1)
+ {
+ return UnwrapException(flattened.InnerExceptions[0]);
+ }
+
+ return flattened;
+ }
+
+ return exception;
+ }
}
}
diff --git a/XLAB2/EkzDirectoryWindow.xaml b/XLAB2/EkzDirectoryWindow.xaml
index 61c7235..6f696f8 100644
--- a/XLAB2/EkzDirectoryWindow.xaml
+++ b/XLAB2/EkzDirectoryWindow.xaml
@@ -65,11 +65,42 @@
+ Command="{Binding AddEkzCommand}">
+
+
+
+
+
+
+
+
+
+
+ Command="{Binding EditEkzCommand}">
+
+
+
+
+
+
+ Command="{Binding DeleteEkzCommand}">
+
+
+
+
+
+
diff --git a/XLAB2/FrpdDirectoryWindow.xaml b/XLAB2/FrpdDirectoryWindow.xaml
index 61876c1..de870b1 100644
--- a/XLAB2/FrpdDirectoryWindow.xaml
+++ b/XLAB2/FrpdDirectoryWindow.xaml
@@ -44,11 +44,42 @@
+ Command="{Binding AddFrpdCommand}">
+
+
+
+
+
+
+
+
+
+
+ Command="{Binding EditFrpdCommand}">
+
+
+
+
+
+
+ Command="{Binding DeleteFrpdCommand}">
+
+
+
+
+
+
@@ -76,11 +107,42 @@
+ Command="{Binding AddFrpdvdCommand}">
+
+
+
+
+
+
+
+
+
+
+ Command="{Binding EditFrpdvdCommand}">
+
+
+
+
+
+
+ Command="{Binding DeleteFrpdvdCommand}">
+
+
+
+
+
+
diff --git a/XLAB2/MainWindow.xaml b/XLAB2/MainWindow.xaml
index d3e3a31..c9e11bd 100644
--- a/XLAB2/MainWindow.xaml
+++ b/XLAB2/MainWindow.xaml
@@ -97,12 +97,44 @@
+ Command="{Binding AddDocumentCommand}">
+
+
+
+
+
+
+
+
+
+
+ Command="{Binding PrintDocumentCommand}">
+
+
+
+
+
+
+ Command="{Binding DeleteDocumentCommand}">
+
+
+
+
+
+
@@ -339,12 +371,49 @@
+ Command="{Binding OpenInstrumentPickerCommand}">
+
+
+
+
+
+
+ Command="{Binding OpenInstrumentTypePickerCommand}">
+
+
+
+
+
+
+ Command="{Binding DeleteSelectedGroupsCommand}">
+
+
+
+
+
+
@@ -440,17 +509,64 @@
+ Command="{Binding CloneLineVerificationCommand}">
+
+
+
+
+
+
+ Command="{Binding PrintVerificationDocumentCommand}">
+
+
+
+
+
+
+ Command="{Binding MarkLinePassedCommand}">
+
+
+
+
+
+
+
+
+
+ Command="{Binding MarkLineRejectedCommand}">
+
+
+
+
+
+
+
+
+
+ Command="{Binding ResetLineVerificationCommand}">
+
+
+
+
+
+
+ Command="{Binding EditPrsnCommand}">
+
+
+
+
+
+
+ Command="{Binding DeletePrsnCommand}">
+
+
+
+
+
+
@@ -82,11 +113,42 @@
+ Command="{Binding AddPrfrCommand}">
+
+
+
+
+
+
+
+
+
+
+ Command="{Binding EditPrfrCommand}">
+
+
+
+
+
+
+ Command="{Binding DeletePrfrCommand}">
+
+
+
+
+
+
@@ -127,11 +189,42 @@
+ Command="{Binding AddPrfrvdCommand}">
+
+
+
+
+
+
+
+
+
+
+ Command="{Binding EditPrfrvdCommand}">
+
+
+
+
+
+
+ Command="{Binding DeletePrfrvdCommand}">
+
+
+
+
+
+
@@ -158,11 +251,42 @@
+ Command="{Binding AddPrdspvCommand}">
+
+
+
+
+
+
+
+
+
+
+ Command="{Binding EditPrdspvCommand}">
+
+
+
+
+
+
+ Command="{Binding DeletePrdspvCommand}">
+
+
+
+
+
+
diff --git a/XLAB2/PsvDataService.cs b/XLAB2/PsvDataService.cs
index 1ed744a..ea1dc3c 100644
--- a/XLAB2/PsvDataService.cs
+++ b/XLAB2/PsvDataService.cs
@@ -88,7 +88,7 @@ ORDER BY fr.NMFRPD;";
return customers;
}
- public Task> LoadCustomersAsync(CancellationToken cancellationToken = default)
+ public async Task> LoadCustomersAsync(CancellationToken cancellationToken = default)
{
const string sql = @"
SELECT
@@ -100,7 +100,7 @@ WHERE z.IDFRPDV IS NOT NULL
GROUP BY z.IDFRPDV, fr.NMFRPD
ORDER BY fr.NMFRPD;";
- return SqlServerConnectionFactory.Current.QueryOpenConnectionAsync(
+ return await SqlServerConnectionFactory.Current.QueryOpenConnectionAsync(
sql,
delegate(SqlDataReader reader)
{
@@ -111,10 +111,7 @@ ORDER BY fr.NMFRPD;";
};
},
ConfigureCommandTimeout,
- cancellationToken).ContinueWith>(delegate(Task> task)
- {
- return task.Result;
- }, cancellationToken, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
+ cancellationToken).ConfigureAwait(false);
}
public IReadOnlyList LoadVerifiers()
@@ -151,7 +148,7 @@ ORDER BY p.PRFIO;";
return verifiers;
}
- public Task> LoadVerifiersAsync(CancellationToken cancellationToken = default)
+ public async Task> LoadVerifiersAsync(CancellationToken cancellationToken = default)
{
const string sql = @"
SELECT
@@ -161,7 +158,7 @@ FROM dbo.PRSN p
WHERE NULLIF(LTRIM(RTRIM(p.PRFIO)), N'') IS NOT NULL
ORDER BY p.PRFIO;";
- return SqlServerConnectionFactory.Current.QueryOpenConnectionAsync(
+ return await SqlServerConnectionFactory.Current.QueryOpenConnectionAsync(
sql,
delegate(SqlDataReader reader)
{
@@ -172,10 +169,7 @@ ORDER BY p.PRFIO;";
};
},
ConfigureCommandTimeout,
- cancellationToken).ContinueWith>(delegate(Task> task)
- {
- return task.Result;
- }, cancellationToken, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
+ cancellationToken).ConfigureAwait(false);
}
public IReadOnlyList LoadVerificationDocumentForms(bool isPassed)
@@ -220,7 +214,7 @@ ORDER BY fr.NMFRD, v.IDVDODVDD;";
return forms;
}
- public Task> LoadVerificationDocumentFormsAsync(bool isPassed, CancellationToken cancellationToken = default)
+ public async Task> LoadVerificationDocumentFormsAsync(bool isPassed, CancellationToken cancellationToken = default)
{
const string sql = @"
SELECT DISTINCT
@@ -235,7 +229,7 @@ WHERE v.IDSPVDOD = 2
AND fr.IDSPVDD = @DocumentTypeId
ORDER BY fr.NMFRD, v.IDVDODVDD;";
- return SqlServerConnectionFactory.Current.QueryOpenConnectionAsync(
+ return await SqlServerConnectionFactory.Current.QueryOpenConnectionAsync(
sql,
delegate(SqlDataReader reader)
{
@@ -252,10 +246,7 @@ ORDER BY fr.NMFRD, v.IDVDODVDD;";
ConfigureCommandTimeout(command);
command.Parameters.Add("@DocumentTypeId", SqlDbType.Int).Value = isPassed ? 6 : 2;
},
- cancellationToken).ContinueWith>(delegate(Task> task)
- {
- return task.Result;
- }, cancellationToken, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
+ cancellationToken).ConfigureAwait(false);
}
public IReadOnlyList LoadSpoiItems()
@@ -293,7 +284,7 @@ ORDER BY s.NMOI, s.KDOI, s.IDSPOI;";
return items;
}
- public Task> LoadSpoiItemsAsync(CancellationToken cancellationToken = default)
+ public async Task> LoadSpoiItemsAsync(CancellationToken cancellationToken = default)
{
const string sql = @"
SELECT
@@ -303,7 +294,7 @@ SELECT
FROM dbo.SPOI s
ORDER BY s.NMOI, s.KDOI, s.IDSPOI;";
- return SqlServerConnectionFactory.Current.QueryOpenConnectionAsync(
+ return await SqlServerConnectionFactory.Current.QueryOpenConnectionAsync(
sql,
delegate(SqlDataReader reader)
{
@@ -315,10 +306,7 @@ ORDER BY s.NMOI, s.KDOI, s.IDSPOI;";
};
},
ConfigureCommandTimeout,
- cancellationToken).ContinueWith>(delegate(Task> task)
- {
- return task.Result;
- }, cancellationToken, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
+ cancellationToken).ConfigureAwait(false);
}
public int AddSpoiItem(SpoiDirectoryItem item)
@@ -499,7 +487,7 @@ ORDER BY s.NMTP, s.IDSPNMTP;";
return items;
}
- public Task> LoadSpnmtpItemsAsync(CancellationToken cancellationToken = default)
+ public async Task> LoadSpnmtpItemsAsync(CancellationToken cancellationToken = default)
{
const string sql = @"
SELECT
@@ -509,7 +497,7 @@ SELECT
FROM dbo.SPNMTP s
ORDER BY s.NMTP, s.IDSPNMTP;";
- return SqlServerConnectionFactory.Current.QueryOpenConnectionAsync(
+ return await SqlServerConnectionFactory.Current.QueryOpenConnectionAsync(
sql,
delegate(SqlDataReader reader)
{
@@ -521,10 +509,7 @@ ORDER BY s.NMTP, s.IDSPNMTP;";
};
},
ConfigureCommandTimeout,
- cancellationToken).ContinueWith>(delegate(Task> task)
- {
- return task.Result;
- }, cancellationToken, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
+ cancellationToken).ConfigureAwait(false);
}
public int AddSpnmtpItem(SpnmtpDirectoryItem item)
@@ -1267,7 +1252,7 @@ ORDER BY names.NMTP, tips.TP, sizeInfo.DPZN, z.NNZV;";
return instruments;
}
- public Task> LoadCustomerInstrumentsAsync(int customerId, CancellationToken cancellationToken = default)
+ public async Task> LoadCustomerInstrumentsAsync(int customerId, CancellationToken cancellationToken = default)
{
const string sql = @"
SELECT
@@ -1343,7 +1328,7 @@ OUTER APPLY
WHERE z.IDFRPDV = @CustomerId
ORDER BY names.NMTP, tips.TP, sizeInfo.DPZN, z.NNZV;";
- return SqlServerConnectionFactory.Current.QueryOpenConnectionAsync(
+ return await SqlServerConnectionFactory.Current.QueryOpenConnectionAsync(
sql,
delegate(SqlDataReader reader)
{
@@ -1371,10 +1356,7 @@ ORDER BY names.NMTP, tips.TP, sizeInfo.DPZN, z.NNZV;";
ConfigureCommandTimeout(command);
command.Parameters.Add("@CustomerId", SqlDbType.Int).Value = customerId;
},
- cancellationToken).ContinueWith>(delegate(Task> task)
- {
- return task.Result;
- }, cancellationToken, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
+ cancellationToken).ConfigureAwait(false);
}
public IReadOnlyList LoadInstrumentTypes()
@@ -1468,7 +1450,7 @@ ORDER BY names.NMTP, tips.TP, sizeInfo.DPZN, sizeInfo.NNGSRS;";
return instrumentTypes;
}
- public Task> LoadInstrumentTypesAsync(CancellationToken cancellationToken = default)
+ public async Task> LoadInstrumentTypesAsync(CancellationToken cancellationToken = default)
{
const string sql = @"
SELECT
@@ -1522,7 +1504,7 @@ OUTER APPLY
) periodByType
ORDER BY names.NMTP, tips.TP, sizeInfo.DPZN, sizeInfo.NNGSRS;";
- return SqlServerConnectionFactory.Current.QueryOpenConnectionAsync(
+ return await SqlServerConnectionFactory.Current.QueryOpenConnectionAsync(
sql,
delegate(SqlDataReader reader)
{
@@ -1546,10 +1528,7 @@ ORDER BY names.NMTP, tips.TP, sizeInfo.DPZN, sizeInfo.NNGSRS;";
};
},
ConfigureCommandTimeout,
- cancellationToken).ContinueWith>(delegate(Task> task)
- {
- return task.Result;
- }, cancellationToken, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
+ cancellationToken).ConfigureAwait(false);
}
public IReadOnlyList FindOpenDocumentConflicts(int customerId, string currentDocumentNumber, IEnumerable candidateLines)
diff --git a/XLAB2/TpvdklWindow.xaml b/XLAB2/TpvdklWindow.xaml
index c44c65e..06a0e55 100644
--- a/XLAB2/TpvdklWindow.xaml
+++ b/XLAB2/TpvdklWindow.xaml
@@ -30,11 +30,42 @@
+ Command="{Binding AddCommand}">
+
+
+
+
+
+
+
+
+
+
+ Command="{Binding EditCommand}">
+
+
+
+
+
+
+ Command="{Binding DeleteCommand}">
+
+
+
+
+
+
diff --git a/XLAB2/TypeSizeDirectoryWindow.xaml b/XLAB2/TypeSizeDirectoryWindow.xaml
index 9f03b1b..2ce2c06 100644
--- a/XLAB2/TypeSizeDirectoryWindow.xaml
+++ b/XLAB2/TypeSizeDirectoryWindow.xaml
@@ -57,14 +57,54 @@
+ Command="{Binding AddTipsCommand}">
+
+
+
+
+
+
+
+
+
+
+ Command="{Binding EditTipsCommand}">
+
+
+
+
+
+
+ Command="{Binding DeleteTipsCommand}">
+
+
+
+
+
+
+ Command="{Binding ManageTpvdklCommand}">
+
+
+
+
+
+
@@ -92,9 +132,40 @@
HeadersVisibility="Column">
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -129,9 +200,40 @@
HeadersVisibility="Column">
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -158,9 +260,40 @@
HeadersVisibility="Column">
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+