Обзор управления приложениями
Все приложения, как правило, используют общий набор функциональных возможностей, которые применяются к реализации и управлению приложениями. В этом разделе представлен обзор функциональных возможностей в классе Application для создания приложений и управления ими.
Класс приложения
В WPF общие функциональные возможности в области приложения инкапсулируются в классе Application. Класс Application включает следующие функции:
Отслеживание и взаимодействие с жизненным циклом приложения.
Получение и обработка параметров командной строки.
Обнаружение и реагирование на необработанные исключения.
Совместное использование свойств и ресурсов области приложения.
Управление окнами в автономных приложениях.
Отслеживание и управление навигацией.
Выполнение распространенных задач с помощью класса приложения
Если вы не заинтересованы во всех деталях класса Application, в следующей таблице перечислены некоторые распространенные задачи для Application и способы их выполнения. Просмотрев связанные API и разделы, вы можете найти дополнительные сведения и пример кода.
Задача | Подход |
---|---|
Получение объекта, представляющего текущее приложение | Используйте свойство Application.Current. |
Добавление начального экрана в приложение | См. добавьте экран-заставку в приложение WPF. |
Запуск приложения | Используйте метод Application.Run. |
Остановка приложения | Используйте метод Shutdown объекта Application.Current. |
Получение аргументов из командной строки | Обработайте событие Application.Startup и используйте свойство StartupEventArgs.Args. См. пример на мероприятии Application.Startup. |
Получение и настройка кода выхода приложения | Задайте свойство ExitEventArgs.ApplicationExitCode в обработчике событий Application.Exit или вызовите метод Shutdown и передайте целое число. |
Обнаружение и реагирование на необработанные исключения | Обработайте событие DispatcherUnhandledException. |
Получение и настройка ресурсов с областью действия приложения | Используйте свойство Application.Resources. |
Использование словаря ресурсов области приложения | См. использование словаря ресурсовApplication-Scope. |
Получение и установка свойств, охватывающих область приложения | Используйте свойство Application.Properties. |
Получение и сохранение состояния приложения | См. свойства Сохранение и Восстановление Application-Scope для сеансов приложений. |
Управление файлами данных, отличными от кода, включая файлы ресурсов, файлы содержимого и файлы источника. | См. ресурс приложения WPF, содержимое и файлы данных . |
Управление окнами в автономных приложениях | См. в обзоре WPF для Windows. |
Учёт и управление навигацией | См. обзор навигации. |
Определение приложения
Чтобы использовать функциональные возможности класса Application, необходимо реализовать определение приложения. Определение приложения WPF — это класс, производный от Application и настроенный с помощью специального параметра MSBuild.
Реализация определения приложения
Обычное определение приложения WPF реализуется с помощью разметки и кода программной части. Это позволяет использовать разметку для декларативного задания свойств приложения, ресурсов и регистрации событий, при обработке событий и реализации поведения конкретного приложения в коде.
В следующем примере показано, как реализовать определение приложения с помощью разметки и кода программной части:
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.App" />
using System.Windows;
namespace SDKSample
{
public partial class App : Application { }
}
Imports System.Windows
Namespace SDKSample
Partial Public Class App
Inherits Application
End Class
End Namespace
Чтобы разрешить совместную работу файла разметки и файла кода, необходимо выполнить следующие действия:
В разметке элемент
Application
должен включать атрибутx:Class
. При создании приложения существованиеx:Class
в файле разметки приводит к созданию класса MSBuildpartial
, который является производным от Application и имеет имя, указанное атрибутомx:Class
. Для этого требуется добавление объявления пространства имен XML для схемы XAML (xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
).В коде программной части класс должен быть классом
partial
с тем же именем, который указан атрибутомx:Class
в разметке и должен быть производным от Application. Это позволяет файлу программной части связаться с классомpartial
, который создается для файла разметки при создании приложения (см. создание приложения WPF).
Заметка
При создании проекта приложения WPF или проекта приложения браузера WPF с помощью Visual Studio определение приложения включается по умолчанию и определяется с помощью разметки и кода.
Этот код является минимальным, необходимым для реализации определения приложения. Однако перед созданием и запуском приложения необходимо выполнить дополнительную конфигурацию MSBuild.
Настройка определения приложения для MSBuild
Для запуска автономных приложений и приложений браузера XAML (XBAPs) требуется реализация определенного уровня инфраструктуры. Наиболее важной частью этой инфраструктуры является точка входа. Когда приложение запускается пользователем, операционная система вызывает точку входа, которая является хорошо известной функцией для запуска приложений.
Предупреждение
Для работы XBAPs требуются устаревшие браузеры, такие как Internet Explorer и старые версии Firefox. Эти старые браузеры обычно не поддерживаются в Windows 10 и Windows 11. Современные браузеры больше не поддерживают технологию, необходимую для приложений XBAP из-за рисков безопасности. Подключаемые модули, позволяющие работу с XBAP, больше не поддерживаются. Дополнительные сведения см. в статье Часто задаваемые вопросы о приложениях, размещенных в браузере WPF (XBAP),.
Традиционно разработчики должны самостоятельно писать некоторые или все эти коды в зависимости от технологии. Однако WPF создает этот код, когда файл разметки определения приложения настроен как элемент MSBuild ApplicationDefinition
, как показано в следующем файле проекта MSBuild:
<Project
DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
...
<ApplicationDefinition Include="App.xaml" />
<Compile Include="App.xaml.cs" />
...
</Project>
Поскольку файл code-behind содержит код, он помечается как элемент MSBuild Compile
, как это является нормой.
Применение этих конфигураций MSBuild к файлам разметки и кода в определении приложения приводит к генерации кода, подобного следующему:
using System;
using System.Windows;
namespace SDKSample
{
public class App : Application
{
public App() { }
[STAThread]
public static void Main()
{
// Create new instance of application subclass
App app = new App();
// Code to register events and set properties that were
// defined in XAML in the application definition
app.InitializeComponent();
// Start running the application
app.Run();
}
public void InitializeComponent()
{
// Initialization code goes here.
}
}
}
Imports System.Windows
Namespace SDKSample
Public Class App
Inherits Application
Public Sub New()
End Sub
<STAThread>
Public Shared Sub Main()
' Create new instance of application subclass
Dim app As New App()
' Code to register events and set properties that were
' defined in XAML in the application definition
app.InitializeComponent()
' Start running the application
app.Run()
End Sub
Public Sub InitializeComponent()
' Initialization code goes here.
End Sub
End Class
End Namespace
Полученный код расширяет определение приложения дополнительным кодом инфраструктуры, который включает метод точки входа Main
. Атрибут STAThreadAttribute применяется к методу Main
, чтобы указать, что основной поток пользовательского интерфейса для приложения WPF является потоком STA, который требуется для приложений WPF. При вызове Main
создается новый экземпляр App
перед вызовом метода InitializeComponent
для регистрации событий и задания свойств, реализованных в разметке. Поскольку InitializeComponent
создается для вас, вам не нужно явно вызывать InitializeComponent
из определения приложения, как это необходимо для реализаций Page и Window. Наконец, вызывается метод Run для запуска приложения.
Получение текущего приложения
Так как функциональные возможности класса Application совместно используются в приложении, для каждого AppDomainможет быть только один экземпляр класса Application. Для этого класс Application реализуется как класс синглтон (см. раздел Реализация Singleton в C#), который создает единственный экземпляр самого себя и предоставляет общий доступ к нему с помощью свойства static
Current.
В следующем коде показано, как получить ссылку на объект Application для текущего AppDomain.
// Get current application
Application current = App.Current;
' Get current application
Dim current As Application = App.Current
Current возвращает ссылку на экземпляр класса Application. Если требуется ссылка на производный класс Application, необходимо привести значение свойства Current, как показано в следующем примере.
// Get strongly-typed current application
App app = (App)App.Current;
' Get strongly-typed current application
Dim appCurrent As App = CType(App.Current, App)
Значение Current можно проверить в любой момент времени существования объекта Application. Тем не менее, вы должны быть осторожны. После создания экземпляра класса Application существует период, в течение которого состояние объекта Application нестабильно. В течение этого периода Application выполняет различные задачи инициализации, необходимые для выполнения кода, включая установку инфраструктуры приложений, задание свойств и регистрацию событий. Если вы пытаетесь использовать объект Application в течение этого периода, код может иметь непредвиденные результаты, особенно если это зависит от заданных свойств Application.
Когда Application завершает работу инициализации, его время существования действительно начинается.
Время существования приложения
Время существования приложения WPF помечается несколькими событиями, которые вызываются Application, чтобы сообщить вам, когда приложение запущено, было активировано и деактивировано и завершено.
Загрузочный экран
Начиная с .NET Framework 3.5 с пакетом обновления 1 (SP1), можно указать изображение, которое будет использоваться в окне запуска или на экране заставки. Класс SplashScreen упрощает отображение окна запуска во время загрузки приложения. Окно SplashScreen создается и отображается перед вызовом Run. Для получения дополнительной информации см. Время запуска приложения и Добавление экрана-заставки в приложение WPF.
Запуск приложения
После вызова Run и инициализации приложения приложение готово к выполнению. Этот момент обозначается при возникновении события Startup:
using System.Windows;
namespace SDKSample
{
public partial class App : Application
{
void App_Startup(object sender, StartupEventArgs e)
{
// Application is running
}
}
}
Namespace SDKSample
Partial Public Class App
Inherits Application
Private Sub App_Startup(ByVal sender As Object, ByVal e As StartupEventArgs)
' Application is running
'</SnippetStartupCODEBEHIND1>
End Class
End Namespace
'</SnippetStartupCODEBEHIND2>
На этом этапе времени существования приложения наиболее распространенная вещь — показать пользовательский интерфейс.
Отображение пользовательского интерфейса
Большинство автономных приложений Windows открывают Window при запуске. Обработчик событий Startup — это одно из мест, откуда это можно сделать, как показано в примере кода ниже.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.App"
Startup="App_Startup" />
using System.Windows;
namespace SDKSample
{
public partial class App : Application
{
void App_Startup(object sender, StartupEventArgs e)
{
// Open a window
MainWindow window = new MainWindow();
window.Show();
}
}
}
Imports System.Windows
Namespace SDKSample
Partial Public Class App
Inherits Application
Private Sub App_Startup(ByVal sender As Object, ByVal e As StartupEventArgs)
' Open a window
Dim window As New MainWindow()
window.Show()
End Sub
End Class
End Namespace
Заметка
Первый Window, который инициализируется в автономном приложении, по умолчанию становится его основным окном. Этот объект Window связан со свойством Application.MainWindow. Значение свойства MainWindow можно изменить программным способом, если главным окном должно быть другое окно, отличное от первого экземпляра Window.
При первом запуске XBAP он, скорее всего, перейдет к Page. Это показано в следующем коде.
<Application
x:Class="SDKSample.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Startup="App_Startup" />
using System;
using System.Windows;
using System.Windows.Navigation;
namespace SDKSample
{
public partial class App : Application
{
void App_Startup(object sender, StartupEventArgs e)
{
((NavigationWindow)this.MainWindow).Navigate(new Uri("HomePage.xaml", UriKind.Relative));
}
}
}
Imports System.Windows
Imports System.Windows.Navigation
Namespace SDKSample
Partial Public Class App
Inherits Application
Private Sub App_Startup(ByVal sender As Object, ByVal e As StartupEventArgs)
CType(Me.MainWindow, NavigationWindow).Navigate(New Uri("HomePage.xaml", UriKind.Relative))
End Sub
End Class
End Namespace
Если вы обрабатываете Startup только для открытия Window или перехода к Page, вместо этого можно задать атрибут StartupUri
в разметке.
В следующем примере показано, как использовать StartupUri из автономного приложения для открытия Window.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
StartupUri="MainWindow.xaml" />
В следующем примере показано, как использовать StartupUri из XBAP для перехода к Page.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
StartupUri="HomePage.xaml" />
Эта разметка имеет тот же эффект, что и предыдущий код для открытия окна.
Заметка
Для получения дополнительной информации о навигации см. раздел Обзор навигации.
Необходимо обработать событие Startup, чтобы открыть Window, если необходимо создать экземпляр его с помощью конструктора без параметров или задать его свойства или подписаться на его события, прежде чем отображать его, или необходимо обработать все аргументы командной строки, предоставленные при запуске приложения.
Обработка аргументов Command-Line
В Windows автономные приложения можно запускать из командной строки или рабочего стола. В обоих случаях аргументы командной строки можно передать приложению. В следующем примере показано приложение, которое запускается с одним аргументом командной строки "/StartMinimized":
wpfapplication.exe /StartMinimized
Во время инициализации приложения WPF извлекает аргументы командной строки из операционной системы и передает их обработчику событий Startup через свойство Args параметра StartupEventArgs. Аргументы командной строки можно извлекать и хранить с помощью следующего кода.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.App"
Startup="App_Startup" />
using System.Windows;
namespace SDKSample
{
public partial class App : Application
{
void App_Startup(object sender, StartupEventArgs e)
{
// Application is running
// Process command line args
bool startMinimized = false;
for (int i = 0; i != e.Args.Length; ++i)
{
if (e.Args[i] == "/StartMinimized")
{
startMinimized = true;
}
}
// Create main application window, starting minimized if specified
MainWindow mainWindow = new MainWindow();
if (startMinimized)
{
mainWindow.WindowState = WindowState.Minimized;
}
mainWindow.Show();
}
}
}
Imports System.Windows
Namespace SDKSample
Partial Public Class App
Inherits Application
Private Sub App_Startup(ByVal sender As Object, ByVal e As StartupEventArgs)
' Application is running
' Process command line args
Dim startMinimized As Boolean = False
Dim i As Integer = 0
Do While i <> e.Args.Length
If e.Args(i) = "/StartMinimized" Then
startMinimized = True
End If
i += 1
Loop
' Create main application window, starting minimized if specified
Dim mainWindow As New MainWindow()
If startMinimized Then
mainWindow.WindowState = WindowState.Minimized
End If
mainWindow.Show()
End Sub
End Class
End Namespace
Код обрабатывает Startup, чтобы проверить, был ли указан аргумент командной строки /StartMinimized; если да, то открывается основное окно с WindowStateMinimized. Обратите внимание, что поскольку свойство WindowState должно быть задано программным способом, основной Window должен быть открыт явным образом в коде.
XBAPs не может получить и обработать аргументы командной строки, так как они запускаются с помощью развертывания ClickOnce (см. развертывание приложения WPF). Однако они могут извлекать и обрабатывать параметры строки запроса из URL-адресов, которые используются для их запуска.
Активация и деактивация приложений
Windows позволяет пользователям переключаться между приложениями. Наиболее распространенным способом является использование сочетания клавиш ALT+TAB. Приложение можно переключить только в том случае, если он имеет видимый Window, который пользователь может выбрать. В настоящее время выбранным Window является активное окно (также известное как окно переднего плана) и является Window, который получает входные данные пользователя. Приложение с активным окном — это активное приложение (или фоновое приложение). Приложение становится активным приложением в следующих случаях:
Программа запускается и отображает Window.
Пользователь переключается из другого приложения, выбрав Window в приложении.
Вы можете определить, когда приложение становится активным, обрабатывая событие Application.Activated.
Аналогичным образом приложение может стать неактивным в следующих обстоятельствах:
Пользователь переключается на другое приложение из текущего.
Когда приложение завершит работу.
Вы можете определить, когда приложение становится неактивным, обрабатывая событие Application.Deactivated.
В следующем коде показано, как обрабатывать события Activated и Deactivated, чтобы определить, активен ли приложение.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.App"
StartupUri="MainWindow.xaml"
Activated="App_Activated"
Deactivated="App_Deactivated" />
using System;
using System.Windows;
namespace SDKSample
{
public partial class App : Application
{
bool isApplicationActive;
void App_Activated(object sender, EventArgs e)
{
// Application activated
this.isApplicationActive = true;
}
void App_Deactivated(object sender, EventArgs e)
{
// Application deactivated
this.isApplicationActive = false;
}
}
}
Imports System.Windows
Namespace SDKSample
Partial Public Class App
Inherits Application
Private isApplicationActive As Boolean
Private Sub App_Activated(ByVal sender As Object, ByVal e As EventArgs)
' Application activated
Me.isApplicationActive = True
End Sub
Private Sub App_Deactivated(ByVal sender As Object, ByVal e As EventArgs)
' Application deactivated
Me.isApplicationActive = False
End Sub
End Class
End Namespace
Window также можно активировать и деактивировать. Дополнительные сведения см. в Window.Activated и Window.Deactivated.
Заметка
Ни Application.Activated, ни Application.Deactivated не вызываются для XBAPs.
Завершение работы приложения
Срок действия приложения заканчивается при завершении работы, что может произойти по следующим причинам:
Пользователь закрывает каждую Window.
Пользователь закрывает основной Window.
Пользователь завершает сеанс Windows, выйдя из системы или выключив компьютер.
Выполнено условие для конкретного приложения.
Для управления завершением работы приложения Application предоставляет метод Shutdown, свойство ShutdownMode и события SessionEnding и Exit.
Заметка
Shutdown можно вызывать только из приложений с UIPermission. Автономные приложения WPF всегда имеют это разрешение. Однако XBAP, выполняемые в песочнице безопасности с частичным доверием в зоне Интернет, не работают.
Режим завершения работы
Большинство приложений завершаются либо при закрытии всех окон, либо при закрытии главного окна. Однако иногда другие условия, относящиеся к приложению, могут определить, когда приложение завершает работу. Вы можете указать условия завершения работы приложения, задав для ShutdownMode одно из следующих значений перечисления ShutdownMode:
Значение по умолчанию ShutdownMode равно OnLastWindowClose. Это означает, что приложение автоматически завершает работу при закрытии последнего окна приложения пользователем. Однако, если приложение должно завершаться при закрытии главного окна, WPF делает это автоматически при установке значения ShutdownMode на OnMainWindowClose. Это показано в следующем примере.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.App"
ShutdownMode="OnMainWindowClose" />
Если у вас есть условия завершения работы для конкретного приложения, установите ShutdownMode на OnExplicitShutdown. В этом случае вы несете ответственность за завершение работы приложения путем явного вызова метода Shutdown; в противном случае приложение будет продолжать работать, даже если все окна закрыты. Обратите внимание, что Shutdown вызывается неявно, если ShutdownMode является либо OnLastWindowClose, либо OnMainWindowClose.
Заметка
ShutdownMode можно задать из XBAP, но оно игнорируется; XBAP всегда закрывается, когда вы покидаете его в браузере или когда закрывается браузер, в котором он размещен. Для получения дополнительных сведений см. обзор навигации .
Окончание сеанса
Условия завершения работы, описанные свойством ShutdownMode, относятся к приложению. В некоторых случаях приложение может прекратить работу в результате внешних обстоятельств. Наиболее распространенное внешнее условие возникает, когда пользователь завершает сеанс Windows следующими действиями:
Выход из системы
Завершает работу
Перезагрузка
Спящий
Чтобы определить, когда сеанс Windows заканчивается, можно обрабатывать событие SessionEnding, как показано в следующем примере.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.App"
StartupUri="MainWindow.xaml"
SessionEnding="App_SessionEnding" />
using System.Windows;
namespace SDKSample
{
public partial class App : Application
{
void App_SessionEnding(object sender, SessionEndingCancelEventArgs e)
{
// Ask the user if they want to allow the session to end
string msg = string.Format("{0}. End session?", e.ReasonSessionEnding);
MessageBoxResult result = MessageBox.Show(msg, "Session Ending", MessageBoxButton.YesNo);
// End session, if specified
if (result == MessageBoxResult.No)
{
e.Cancel = true;
}
}
}
}
Imports System.Windows
Namespace SDKSample
Partial Public Class App
Inherits Application
Private Sub App_SessionEnding(ByVal sender As Object, ByVal e As SessionEndingCancelEventArgs)
' Ask the user if they want to allow the session to end
Dim msg As String = String.Format("{0}. End session?", e.ReasonSessionEnding)
Dim result As MessageBoxResult = MessageBox.Show(msg, "Session Ending", MessageBoxButton.YesNo)
' End session, if specified
If result = MessageBoxResult.No Then
e.Cancel = True
End If
End Sub
End Class
End Namespace
В этом примере код проверяет свойство ReasonSessionEnding, чтобы определить, как завершается сеанс Windows. Это значение используется для отображения сообщения подтверждения пользователю. Если пользователь не хочет, чтобы сеанс закончился, код задает Canceltrue
, чтобы предотвратить завершение сеанса Windows.
Заметка
SessionEnding не вызывается для XBAPs.
Выход
При завершении работы приложения может потребоваться выполнить определенную окончательную обработку, например сохранение состояния приложения. В этих ситуациях можно обрабатывать событие Exit, как это делает обработчик событий App_Exit
в следующем примере. Он определяется как обработчик событий в файле App.xaml. Его реализация выделена в файлах App.xaml.cs и Application.xaml.vb.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.App"
StartupUri="MainWindow.xaml"
Startup="App_Startup"
Exit="App_Exit">
<Application.Resources>
<SolidColorBrush x:Key="ApplicationScopeResource" Color="White"></SolidColorBrush>
</Application.Resources>
</Application>
using System.Windows;
using System.IO;
using System.IO.IsolatedStorage;
namespace SDKSample
{
public partial class App : Application
{
string filename = "App.txt";
public App()
{
// Initialize application-scope property
this.Properties["NumberOfAppSessions"] = 0;
}
private void App_Startup(object sender, StartupEventArgs e)
{
// Restore application-scope property from isolated storage
IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForDomain();
try
{
using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filename, FileMode.Open, storage))
using (StreamReader reader = new StreamReader(stream))
{
// Restore each application-scope property individually
while (!reader.EndOfStream)
{
string[] keyValue = reader.ReadLine().Split(new char[] {','});
this.Properties[keyValue[0]] = keyValue[1];
}
}
}
catch (FileNotFoundException ex)
{
// Handle when file is not found in isolated storage:
// * When the first application session
// * When file has been deleted
}
}
private void App_Exit(object sender, ExitEventArgs e)
{
// Persist application-scope property to isolated storage
IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForDomain();
using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream(filename, FileMode.Create, storage))
using (StreamWriter writer = new StreamWriter(stream))
{
// Persist each application-scope property individually
foreach (string key in this.Properties.Keys)
{
writer.WriteLine("{0},{1}", key, this.Properties[key]);
}
}
}
}
}
Imports System.IO
Imports System.IO.IsolatedStorage
Namespace SDKSample
Partial Public Class App
Inherits Application
Private filename As String = "App.txt"
Public Sub New()
' Initialize application-scope property
Me.Properties("NumberOfAppSessions") = 0
End Sub
Private Sub App_Startup(ByVal sender As Object, ByVal e As StartupEventArgs)
' Restore application-scope property from isolated storage
Dim storage As IsolatedStorageFile = IsolatedStorageFile.GetUserStoreForDomain()
Try
Using stream As New IsolatedStorageFileStream(filename, FileMode.Open, storage)
Using reader As New StreamReader(stream)
' Restore each application-scope property individually
Do While Not reader.EndOfStream
Dim keyValue() As String = reader.ReadLine().Split(New Char() {","c})
Me.Properties(keyValue(0)) = keyValue(1)
Loop
End Using
End Using
Catch ex As FileNotFoundException
' Handle when file is not found in isolated storage:
' * When the first application session
' * When file has been deleted
End Try
End Sub
Private Sub App_Exit(ByVal sender As Object, ByVal e As ExitEventArgs)
' Persist application-scope property to isolated storage
Dim storage As IsolatedStorageFile = IsolatedStorageFile.GetUserStoreForDomain()
Using stream As New IsolatedStorageFileStream(filename, FileMode.Create, storage)
Using writer As New StreamWriter(stream)
' Persist each application-scope property individually
For Each key As String In Me.Properties.Keys
writer.WriteLine("{0},{1}", key, Me.Properties(key))
Next key
End Using
End Using
End Sub
End Class
End Namespace
Полный пример см. в разделе Сохранение и восстановление Application-Scope свойств Application-Scope сеансов приложений.
Exit может обрабатываться как автономными приложениями, так и XBAP. Для XBAPs Exit возникает при следующих обстоятельствах:
От XBAP осуществляется переход.
Когда закрывается вкладка, хранящая XBAP, в Internet Explorer.
При закрытии браузера.
Код выхода
Приложения в основном запускаются операционной системой в ответ на запрос пользователя. Однако приложение можно запустить другим приложением для выполнения определенной задачи. После завершения работы запущенного приложения может потребоваться знать условие завершения работы запущенного приложения. В таких ситуациях Windows позволяет приложениям возвращать код выхода приложения при завершении работы. По умолчанию приложения WPF возвращают значение кода выхода 0.
Заметка
При отладке из Visual Studio код выхода приложения отображается в окне выходных данных
The program '[5340] AWPFApp.vshost.exe: Managed' has exited with code 0 (0x0).
Откройте окно выходных данных, щелкнув выходные данные в меню представление.
Чтобы изменить код выхода, можно вызвать перегрузку Shutdown(Int32), которая принимает целое число в качестве кода выхода.
// Shutdown and return a non-default exit code
Application.Current.Shutdown(-1);
' Shutdown and return a non-default exit code
Application.Current.Shutdown(-1)
Вы можете определить значение кода выхода и изменить его, обрабатывая событие Exit. Обработчику событий Exit передается ExitEventArgs, который предоставляет доступ к коду выхода через свойство ApplicationExitCode. Дополнительные сведения см. в Exit.
Заметка
Код выхода можно задать как в автономных приложениях, так и в XBAPs. Однако значение кода выхода игнорируется для XBAPs.
Необработанные исключения
Иногда приложение может завершить работу в нестандартных условиях, таких как возникновение непредвиденного исключения. В этом случае у приложения может не быть кода для обнаружения и обработки исключения. Этот тип исключения является необработанным исключением; Уведомление, аналогичное приведенному на следующем рисунке, отображается перед закрытием приложения.
С точки зрения пользовательского интерфейса приложение лучше избежать этого поведения по умолчанию, выполнив некоторые или все из следующих действий:
Отображение понятных сведений.
Попытка сохранить работу приложения.
Запись подробных сведений об исключениях, понятных для разработчиков, в журнале событий Windows.
Реализация этой поддержки зависит от возможности обнаружения необработанных исключений, что представляет собой событие DispatcherUnhandledException.
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SDKSample.App"
StartupUri="MainWindow.xaml"
DispatcherUnhandledException="App_DispatcherUnhandledException" />
using System.Windows;
using System.Windows.Threading;
namespace SDKSample
{
public partial class App : Application
{
void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
// Process unhandled exception
// Prevent default unhandled exception processing
e.Handled = true;
}
}
}
Imports System.Windows
Imports System.Windows.Threading
Namespace SDKSample
Partial Public Class App
Inherits Application
Private Sub App_DispatcherUnhandledException(ByVal sender As Object, ByVal e As DispatcherUnhandledExceptionEventArgs)
' Process unhandled exception
' Prevent default unhandled exception processing
e.Handled = True
End Sub
End Class
End Namespace
Обработчику событий DispatcherUnhandledException передается параметр DispatcherUnhandledExceptionEventArgs, который содержит контекстные сведения о необработанном исключении, включая само исключение (DispatcherUnhandledExceptionEventArgs.Exception). Эти сведения можно использовать для определения способа обработки исключения.
При обработке DispatcherUnhandledExceptionнеобходимо задать для свойства DispatcherUnhandledExceptionEventArgs.Handled значение true
; В противном случае WPF по-прежнему считает исключение необработанным и возвращается к поведению по умолчанию, описанному ранее. Если возникает необработанное исключение и либо событие DispatcherUnhandledException не обрабатывается, либо событие обрабатывается, но Handled установлено значение false
, приложение завершает работу немедленно. Кроме того, никакие другие Application события не вызываются. Следовательно, необходимо обработать DispatcherUnhandledException, если у приложения есть код, который должен выполняться до завершения работы приложения.
Хотя приложение может завершить работу в результате необработанного исключения, приложение обычно завершает работу в ответ на запрос пользователя, как описано в следующем разделе.
События времени существования приложения
Автономные приложения и XBAPs не имеют точно одинаковых времени существования. На следующем рисунке показаны ключевые события в течение времени существования автономного приложения и показывается последовательность, в которой они вызываются.
Аналогичным образом, на следующем рисунке показаны ключевые события в течение жизненного цикла XBAP и показана последовательность, в которой они возникают.
См. также
- Application
- Обзор WPF Windows
- Обзор навигации
- Ресурсы, содержимое и файлы данных приложения WPF
- URI пакета в WPF
- модель приложений : практическое руководство
- разработка приложений
.NET Desktop feedback