This article is currently in the process of being translated into Bulgarian (~94% done).
Handling exceptions in WPF
Ако сте запознати с C# или някой от другите езици на .NET, които може да използвате с WPF, тогава обработката на изключения не трябва да е нещо ново за вас: винаги, когато имате част от код, който е вероятно да хвърли изключение, използвайте try-catch, за да се справите грациозно с него. Например:
private void Button_Click(object sender, RoutedEventArgs e)
{
string s = null;
s.Trim();
}
Очевидно ще има проблем, тъй като се опитваме да изпълним метода Trim() върху променлива, която в момента е null. Ако не се справите с изключението, вашето приложение ще се срине и Windows ще трябва да се справи с проблема. Както можете да видите, това не е много удобно за потребителя:
В този случай потребителят ще бъде принуден да затвори вашето приложение поради такава проста и лесна за избягване грешка. Така че, ако знаете, че нещата може да се объркат, тогава трябва да използвате блок try-catch:
private void Button_Click(object sender, RoutedEventArgs e)
{
string s = null;
try
{
s.Trim();
}
catch(Exception ex)
{
MessageBox.Show("A handled exception just occurred: " + ex.Message, "Exception Sample", MessageBoxButton.OK, MessageBoxImage.Warning);
}
}
Въпреки това, понякога дори най-простият код може да хвърли изключение и вместо да обгръщате всеки един ред код с блок try-catch, WPF ви позволява да обработвате всички необработени изключения глобално. Това се прави чрез събитието DispatcherUnhandledException в класа Application. Ако е абониран (чрез обявяване в App.xaml и App.xaml.cs), WPF ще извика метода, след като бъде хвърлено изключение, което не се обработва във вашия собствен код. Ето пълен пример, на базата на това, през които току-що преминахме:
<Window x:Class="WpfTutorialSamples.WPF_Application.ExceptionHandlingSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ExceptionHandlingSample" Height="200" Width="200">
<Grid>
<Button HorizontalAlignment="Center" VerticalAlignment="Center" Click="Button_Click">
Do something bad!
</Button>
</Grid>
</Window>
using System;
using System.Windows;
namespace WpfTutorialSamples.WPF_Application
{
public partial class ExceptionHandlingSample : Window
{
public ExceptionHandlingSample()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
string s = null;
try
{
s.Trim();
}
catch(Exception ex)
{
MessageBox.Show("A handled exception just occurred: " + ex.Message, "Exception Sample", MessageBoxButton.OK, MessageBoxImage.Warning);
}
s.Trim();
}
}
}
Забележете, че извиквам метода Trim() още веднъж, извън блока try-catch, така че първото извикване се обработва, докато второто - не. За втория път се нуждаем от магията в App.xaml:
<Application x:Class="WpfTutorialSamples.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DispatcherUnhandledException="Application_DispatcherUnhandledException"
StartupUri="WPF Application/ExceptionHandlingSample.xaml">
<Application.Resources>
</Application.Resources>
</Application>
using System;
using System.Windows;
namespace WpfTutorialSamples
{
public partial class App : Application
{
private void Application_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
MessageBox.Show("An unhandled exception just occurred: " + e.Exception.Message, "Exception Sample", MessageBoxButton.OK, MessageBoxImage.Error);
e.Handled = true;
}
}
}
Обработваме изключението подобно на локалния try-catch, но с малко по-различен текст и изображение в полето за съобщения. Също така забележете, че е зададено свойството e.Handled на true. Това казва на WPF, че сме приключили с това изключение и нищо друго не трябва да се прави по въпроса.
Резюме
Обработката на изключения е много важна част от всяко приложение и за щастие WPF и .NET улесняват обработката на изключения както локално, така и глобално. Трябва да обработвате изключенията локално, когато има смисъл, и да използвате само глобалната обработка като резервен механизъм, тъй като локалната обработка ви позволява да бъдете по-конкретни и да се справите с проблема по по-специализиран начин.