Información general sobre la administración de aplicaciones

Este tema proporciona información general sobre los servicios de Windows Presentation Foundation (WPF) para crear y administrar aplicaciones. El kernel de una aplicación WPF es la clase Application, que admite diversos servicios básicos de la aplicación. En este tema se proporciona una introducción a los servicios más importantes.

Este tema contiene las secciones siguientes.

  • Clase Application
  • Definición de aplicación
  • Obtener la aplicación actual
  • Duración de la aplicación
  • Otros servicios de aplicación
  • Temas relacionados

Clase Application

Una aplicación se compone de muchos elementos específicos de la aplicación, entre ellos la user interface (UI), la lógica de negocios, la lógica de acceso a datos, los controles y los datos. Estos elementos difieren habitualmente de una aplicación a otra. Sin embargo, todas las aplicaciones tienden a compartir un conjunto común de funcionalidades que facilita la implementación y la administración de la aplicación. En WPF, esta funcionalidad común para el ámbito de la aplicación se encapsula en la clase Application, que proporciona los siguientes servicios:

  • Crear y administrar la infraestructura común de las aplicaciones.

  • Realizar el seguimiento e interactuar con la duración de la aplicación.

  • Recuperar y procesar los parámetros de la línea de comandos.

  • Compartir propiedades y recursos del ámbito de la aplicación.

  • Detectar y responder a las excepciones no controladas.

  • Devolver códigos de salida.

  • Administrar las ventanas en las aplicaciones independientes (vea Información general sobre ventanas de WPF).

  • Realizar el seguimiento y administrar la navegación (vea Información general sobre navegación).

Para utilizar estos servicios en la aplicación, necesita utilizar la clase Application para implementar una definición de aplicación.

Definición de aplicación

Una definición de aplicación WPF es una clase que deriva de Application y se configura con un valor de Microsoft build engine (MSBuild) especial.

Implementar una definición de aplicación

Una definición de aplicación WPF típica se implementa utilizando tanto marcado como código subyacente. Esto permite utilizar marcado para establecer mediante declaración propiedades, recursos y eventos de registro de la aplicación, mientras que el control de eventos y la implementación del comportamiento específico de la aplicación se realizan en el código subyacente.

En el ejemplo siguiente se muestra cómo implementar una definición de aplicación utilizando tanto marcado como código subyacente:

<Application 
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" 
  x:Class="SDKSample.App" />

Imports Microsoft.VisualBasic
Imports System.Windows ' Application

Namespace SDKSample
    Partial Public Class App
        Inherits Application
    End Class
End Namespace
using System.Windows;  // Application

namespace SDKSample
{
    public partial class App : Application { }
}

Para que un archivo de marcado y un archivo de código subyacente funcionen conjuntamente, debe ocurrir lo siguiente:

  • En el marcado, el elemento Application debe incluir el atributo x:Class. Al compilar la aplicación, la existencia de x:Class en el archivo de marcado permite que MSBuild cree una clase partial que se derive de Application y tenga el nombre especificado por el atributo x:Class. Para ello, es necesario agregar una declaración de espacio de nombres XML para el esquema XAML (xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml").

  • En el archivo de código subyacente, la clase debe ser una clase partial con el mismo nombre que el especificado por el atributo x:Class en el marcado, y debe derivarse de Application. Esto permite que el archivo de código subyacente se asocie a la clase partial que se genera para el archivo de marcado cuando se crea la aplicación (vea Compilar una aplicación de WPF (WPF)).

NotaNota

Al crearse un nuevo proyecto de Aplicación WPF o Aplicación de explorador WPF mediante Microsoft Visual Studio, se incluye de forma predeterminada una definición de aplicación, que se define utilizando tanto marcado como código subyacente.

Este código es el mínimo necesario para implementar una definición de aplicación. Sin embargo, es necesario realizar una configuración adicional de MSBuild en la definición de aplicación antes de generar y ejecutar la aplicación.

Configurar la definición de aplicación para MSBuild

Las aplicaciones independientes y XAML browser applications (XBAPs) requieren la implementación de un cierto nivel de infraestructura para poderse ejecutar. La parte más importante de esta infraestructura es el punto de entrada. Cuando un usuario inicia una aplicación, el sistema operativo llama al punto de entrada, que es una función conocida para iniciar las aplicaciones.

Tradicionalmente, los desarrolladores necesitaban escribir todo o parte de este código, según la tecnología. Sin embargo, WPF se encarga de generar este código cuando el archivo de marcado de la definición de aplicación está configurado como un elemento MSBuildApplicationDefinition, tal como se muestra en el siguiente archivo de proyecto de MSBuild:

<Project 
  DefaultTargets="Build"
  xmlns="https://schemas.microsoft.com/developer/msbuild/2003">
  ...
  <ApplicationDefinition Include="App.xaml" />
  <Compile Include="App.xaml.cs" />
  ...
</Project>

Dado que el archivo de código subyacente contiene código, se marca como un elemento MSBuildCompile, lo cual es normal.

La aplicación de estas configuraciones de MSBuild a los archivos de código subyacente y marcado de una definición de aplicación hace que MSBuild genere código como el siguiente:


Imports Microsoft.VisualBasic
Imports System ' STAThread
Imports System.Windows ' Application

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()


...


        End Sub
    End Class
End Namespace
using System; // STAThread
using System.Windows; // Application

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()
        {


...


        }
    }
}

El código resultante amplía la definición de aplicación con código de infraestructura adicional, que incluye el método de punto de entrada Main. El atributo STAThreadAttribute se aplica al método Main para indicar que el subproceso principal de la UI para la aplicación de WPF es un subproceso STA, necesario para las aplicaciones de WPF. Cuando se invoca, Main crea una nueva instancia de App antes de llamar al método InitializeComponent para registrar los eventos y establecer las propiedades que se implementan en el marcado. Dado que se genera InitializeComponent, no es necesario llamar explícitamente a InitializeComponent desde una definición de aplicación tal y como se hace para las implementaciones de Page y Window. Finalmente, se llama al método Run para iniciar la aplicación.

Obtener la aplicación actual

Dado que los servicios de la clase Application se comparten en una aplicación, puede haber solamente una instancia de la clase Application por AppDomain. Para exigir esto, la clase Application se implementa como una clase singleton (vea Implementing Singleton in C#), que crea una única instancia de sí misma y proporciona acceso compartido a ella con la propiedad static Current.

En el código siguiente se muestra cómo adquirir una referencia al objeto Application para el objeto AppDomain actual.

            ' Get current application
            Dim current As Application = App.Current
// Get current application
Application current = App.Current;

Current devuelve una referencia a una instancia de la clase Application. Si desea obtener una referencia a la clase derivada de Application, debe convertir el valor de la propiedad Current, como se muestra en el ejemplo siguiente.

            ' Get strongly-typed current application
            Dim appCurrent As App = CType(App.Current, App)
// Get strongly-typed current application
App app = (App)App.Current;

Puede inspeccionar el valor de Current en cualquier punto de la duración de un objeto Application. Sin embargo, se recomienda tener cuidado. Tras crearse una instancia de la clase Application, el estado del objeto Application es incoherente durante un período de tiempo. Durante este período, Application realiza las diversas tareas de inicialización necesarias para que se ejecute el código, incluido el establecimiento de la infraestructura de la aplicación, la configuración de las propiedades y el registro de los eventos. Si intenta utilizar el objeto Application durante este período, el código puede generar resultados inesperados, en particular si depende de las diversas propiedades de Application que se están estableciendo.

Cuando Application completa sus tareas de inicialización, se inicia realmente su duración.

Duración de la aplicación

La duración de una aplicación WPF está marcada por varios eventos que Application provoca para indicar cuándo se inicia la aplicación, cuándo se activa y se desactiva, y cuándo se cierra.

Este tema contiene las subsecciones siguientes.

  • Pantalla de presentación
  • Iniciar una aplicación
  • Mostrar una interfaz de usuario
  • Procesar argumentos de la línea de comandos
  • Activación y desactivación de aplicaciones
  • Cierre de la aplicación
  • Excepciones no controladas
  • Eventos de duración de la aplicación

Pantalla de presentación

A partir de .NET Framework 3.5 SP1, puede especificar una imagen para usarla en una ventana de inicio o pantalla de presentación. La clase SplashScreen facilita el mostrar una ventana de inicio mientras se carga la aplicación. La ventana SplashScreense crea y muestra antes de que se llame a Run. Para obtener más información, vea Tiempo de inicio de una aplicación y Cómo: Agregar una pantalla de presentación a una aplicación WPF.

Iniciar una aplicación

Después de llamarse a Run e inicializarse la aplicación, esta está lista para ejecutarse. El evento Startup indica este momento:


Imports Microsoft.VisualBasic
Imports System.Windows ' Application, StartupEventArgs, WindowState

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private Sub App_Startup(ByVal sender As Object, ByVal e As StartupEventArgs)
            ' Application is running


...


        End Sub
    End Class
End Namespace
using System.Windows; // Application, StartupEventArgs, WindowState

namespace SDKSample
{
    public partial class App : Application
    {
        void App_Startup(object sender, StartupEventArgs e)
        {
            // Application is running


...


        }
    }
}

En este punto de la duración de una aplicación, se suele mostrar una UI.

Mostrar una interfaz de usuario

La mayoría de las aplicaciones independientes para Windows abren un objeto Window cuando comienzan a ejecutarse. El controlador de eventos Startup es una de las ubicaciones donde se puede hacer esto, tal como se muestra en el código siguiente.

<Application
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.App" 
  Startup="App_Startup" />

Imports Microsoft.VisualBasic
Imports System.Windows ' Application, StartupEventArgs

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
using System.Windows; // Application, StartupEventArgs

namespace SDKSample
{
    public partial class App : Application
    {
        void App_Startup(object sender, StartupEventArgs e)
        {
            // Open a window
            MainWindow window = new MainWindow();
            window.Show();
        }
    }
}
NotaNota

El primer objeto Window del que se va a crear una instancia en una aplicación independiente se convierte de forma predeterminada en la ventana principal de la aplicación.A este objeto Window se hace referencia mediante la propiedad Application.MainWindow.El valor de la propiedad MainWindow se puede cambiar mediante programación si una ventana diferente del primer objeto Window del que se creó una instancia debe ser la ventana principal.

Cuando se inicia por primera vez una aplicación XBAP, lo más probable es que navegue a un objeto Page. Esto se muestra en el código siguiente.

<Application 
  x:Class="SDKSample.App"
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  Startup="App_Startup" />

Imports System ' Uri, UriKind, EventArgs, Console
Imports System.Windows ' Application, StartupEventArgs
Imports System.Windows.Navigation ' NavigationWindow

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
using System; // Uri, UriKind, EventArgs, Console
using System.Windows; // Application, StartupEventArgs
using System.Windows.Navigation; // NavigationWindow

namespace SDKSample
{
    public partial class App : Application
    {        
        void App_Startup(object sender, StartupEventArgs e)
        {
            ((NavigationWindow)this.MainWindow).Navigate(new Uri("HomePage.xaml", UriKind.Relative));
        }
    }
}

Si controla Startup para que abra solamente un objeto Window o navegue a un objeto Page, podrá establecer el atributo StartupUri en el marcado.

En el ejemplo siguiente se muestra cómo utilizar StartupUri desde una aplicación independiente para abrir un objeto Window.

<Application
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    StartupUri="MainWindow.xaml" />

En el ejemplo siguiente se muestra cómo utilizar la propiedad StartupUri de una aplicación XBAP para navegar a un objeto Page.

<Application
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    StartupUri="HomePage.xaml" />

Este marcado tiene el mismo efecto que el código anterior para abrir una ventana.

NotaNota

Para obtener más información sobre la navegación, vea Información general sobre navegación.

Debe controlar el evento Startup para que se abra un objeto Window si necesita crear instancias del mismo mediante un constructor no predeterminado, o bien, si necesita establecer sus propiedades o suscribirse a sus eventos antes de que se muestre, o bien, si necesita procesar los argumentos de línea de comandos proporcionados al iniciarse la aplicación.

Procesar argumentos de la línea de comandos

En Windows, las aplicaciones independientes pueden iniciarse desde el símbolo del sistema o desde el escritorio. En ambos casos, es posible pasar argumentos de la línea de comandos a la aplicación. En el ejemplo siguiente se muestra una aplicación que se inicia con un solo argumento de la línea de comandos, "/StartMinimized":

wpfapplication.exe /StartMinimized

Durante la inicialización de la aplicación, WPF recupera los argumentos de la línea de comandos del sistema operativo y los pasa al controlador de eventos Startup a través de la propiedad Args del parámetro StartupEventArgs. Puede recuperar y almacenar los argumentos de la línea de comandos utilizando código como el siguiente.

<Application
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.App"
  Startup="App_Startup" />

Imports Microsoft.VisualBasic
Imports System.Windows ' Application, StartupEventArgs, WindowState

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
using System.Windows; // Application, StartupEventArgs, WindowState

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();
        }
    }
}

El código controla el evento Startup para comprobar si se proporcionó el argumento de la línea de comandos /StartMinimized; en caso afirmativo, abre la ventana principal con el valor de WindowState Minimized. Observe que, dado que la propiedad WindowState debe establecerse mediante programación, el objeto Window principal se debe abrir explícitamente en el código.

Las XBAPs no pueden recuperar ni procesar los argumentos de la línea de comandos porque se inician usando la implementación de ClickOnce (vea Implementar una aplicación de WPF). Sin embargo, pueden recuperar y procesar los parámetros de las cadenas de consulta de las direcciones URL que se usan para iniciarlas.

Activación y desactivación de aplicaciones

Windows permite a los usuarios cambiar de una aplicación a otra. El método más común es utilizar la combinación de teclas ALT+TAB. Solamente se puede cambiar a una aplicación si tiene un objeto Window visible que el usuario pueda seleccionar. El objeto Window seleccionado actualmente es la ventana activa (también conocida como ventana de primer plano) y es el objeto Window que recibe los datos proporcionados por el usuario. La aplicación con la ventana activa es la aplicación activa (o aplicación de primer plano). Una aplicación se convierte en la aplicación activa en las siguientes circunstancias:

  • Se inicia y muestra un objeto Window.

  • Un usuario cambia desde otra aplicación seleccionando un objeto Window de la aplicación.

Para detectar cuándo una aplicación se convierte en la aplicación activa, controle el evento Application.Activated.

De manera similar, una aplicación puede volverse inactiva en las circunstancias siguientes:

  • Un usuario cambia a otra aplicación desde la actual.

  • Cuando se cierra la aplicación.

Para detectar cuándo una aplicación se vuelve inactiva, controle el evento Application.Deactivated.

En el código siguiente se muestra cómo controlar los eventos Activated y Deactivated para determinar si una aplicación está activa.

<Application 
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.App"
  StartupUri="MainWindow.xaml"
  Activated="App_Activated" 
  Deactivated="App_Deactivated" />

Imports Microsoft.VisualBasic
Imports System ' EventArgs
Imports System.Windows ' Application

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
using System; // EventArgs
using System.Windows; // Application

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;
        }
    }
}

Un objeto Window también se puede activar y desactivar. Para obtener más información, vea Window.Activated y Window.Deactivated.

NotaNota

En el caso de las XBAPs, no se provoca el evento Application.Activated ni el evento Application.Deactivated.

Cierre de la aplicación

La duración de una aplicación finaliza cuando se cierra, lo cual puede ocurrir por las razones siguientes:

  • El usuario cierra todos los objetos Window.

  • El usuario cierra el objeto Window principal.

  • El usuario finaliza la sesión de Windows cerrando sesión o apagando.

  • Se ha cumplido una condición específica de la aplicación.

Para facilitar la administración del cierre de la aplicación, Application proporciona el método Shutdown, la propiedad ShutdownMode y los eventos SessionEnding y Exit.

NotaNota

Solamente se puede llamar a Shutdown desde aplicaciones que tengan UIPermission.Las aplicaciones WPF independientes siempre tienen este permiso.Sin embargo, las XBAPs que se ejecutan en el recinto de seguridad de confianza parcial de la zona de Internet no lo tienen.

Modo de apagado

La mayoría de las aplicaciones se apagan cuando se cierran todas las ventanas o cuando se cierra la ventana principal. En ocasiones, sin embargo, puede haber otras condiciones específicas de la aplicación que determinen cuándo se cierra la aplicación. Puede especificar las condiciones en las que se cerrará la aplicación estableciendo la propiedad ShutdownMode en uno de los valores siguientes de la enumeración ShutdownMode:

El valor predeterminado de ShutdownMode es OnLastWindowClose, lo que significa que una aplicación se cierra automáticamente cuando el usuario cierra la última ventana de la aplicación. Sin embargo, si la aplicación debe cerrarse cuando se cierre la ventana principal, WPF lo hará automáticamente si establece ShutdownMode en OnMainWindowClose. Esto se muestra en el ejemplo siguiente.

<Application
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.App"
    ShutdownMode="OnMainWindowClose" />

En el caso de condiciones de cierre específicas de la aplicación, establezca ShutdownMode en OnExplicitShutdown. En este caso, es su responsabilidad cerrar la aplicación llamando al método Shutdown; de lo contrario, la aplicación seguirá ejecutándose aunque se cierren todas las ventanas. Observe que se llama implícitamente a Shutdown cuando el valor de ShutdownMode es OnLastWindowClose u OnMainWindowClose.

NotaNota

ShutdownMode se puede establecer desde una aplicación XBAP, pero se omite; una aplicación XBAP siempre se cierra cuando se navega fuera de ella en un explorador o cuando se cierra el explorador que hospeda la aplicación XBAP.Para obtener más información, vea Información general sobre navegación.

Fin de la sesión

Las condiciones de apagado que describe la propiedad ShutdownMode son específicas de la aplicación. En algunos casos, sin embargo, es posible que una aplicación se cierre como resultado de una condición externa. La condición externa más común se produce cuando el usuario finaliza la sesión de Windows mediante las acciones siguientes:

  • Cerrar sesión

  • Apagar

  • Reiniciar

  • Hibernar

Para detectar cuándo finaliza una sesión de Windows, puede controlar el evento SessionEnding, tal como se muestra en el ejemplo siguiente.

<Application 
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.App"
    StartupUri="MainWindow.xaml"
    SessionEnding="App_SessionEnding" />

Imports Microsoft.VisualBasic
Imports System.Windows ' Application, SessionEndingCancelEventArgs, MessageBox, MessageBoxResult, MessageBoxButton

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
using System.Windows; // Application, SessionEndingCancelEventArgs, MessageBox, MessageBoxResult, MessageBoxButton

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;
            }
        }
    }
}

En este ejemplo, el código inspecciona la propiedad ReasonSessionEnding para determinar cómo finaliza la sesión de Windows. Utiliza este valor para mostrar un mensaje de confirmación al usuario. Si el usuario no desea que la sesión finalice, el código establece Cancel en true para evitar que finalice la sesión de Windows.

NotaNota

No se provoca el evento SessionEnding para las XBAPs.

Exit

Cuando una aplicación se apaga, es posible que necesite realizar algunos últimos procesos, como conservar el estado de la aplicación. Para estas situaciones, puede controlar el evento Exit.

<Application
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.App"
    StartupUri="MainWindow.xaml" 
    Startup="App_Startup" 
    Exit="App_Exit">


...


</Application>
Imports System.IO ' StreamReader, FileMode
Imports System.IO.IsolatedStorage ' IsolatedStorageFile, IsolatedStorageFileStream

Namespace SDKSample
    Partial Public Class App
        Inherits Application
        Private filename As String = "App.txt"



...


        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
using System.Windows; // Application, StartupEventArgs
using System.IO; // StreamReader, FileMode
using System.IO.IsolatedStorage; // IsolatedStorageFile, IsolatedStorageFileStream

namespace SDKSample
{
    public partial class App : Application
    {
        string filename = "App.txt";



...


        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]);
                }
            }
        }
    }
}

Para obtener el ejemplo completo, consulte Cómo: Conservar y restaurar propiedades en el ámbito de aplicación a través de sesiones de aplicación.

El evento Exit puede ser controlado tanto por las aplicaciones independientes como por las XBAPs. En el caso de las XBAPs, se provoca el evento Exit en las circunstancias siguientes:

  • Cuando se navega fuera de una aplicación XBAP.

  • En Internet Explorer 7, cuando se cierra la ficha en la que se hospeda la aplicación XBAP.

  • Cuando se cierra el explorador.

Código de salida

La mayoría de las aplicaciones las inicia el sistema operativo en respuesta a una solicitud del usuario. Sin embargo, una aplicación puede ser iniciada por otra aplicación para realizar alguna tarea concreta. Cuando la aplicación iniciada se cierra, es posible que la aplicación que la inició desee conocer la condición en la que se cerró la aplicación iniciada. En estas situaciones, Windows permite que las aplicaciones devuelvan un código de salida al cerrarse. De forma predeterminada, las aplicaciones WPF devuelven 0 como valor de código de salida.

NotaNota

Cuando se depura desde Visual Studio, el código de salida de la aplicación se muestra en la Ventana de salida cuando se cierra la aplicación, en un mensaje similar al siguiente:

The program '[5340] AWPFApp.vshost.exe: Managed' has exited with code 0 (0x0).

Para abrir la Ventana de salida, haga clic en Resultados en el menú Ver.

Para cambiar el código de salida, puede llamar a la sobrecarga Shutdown(Int32), que acepta un argumento de tipo entero como código de salida:

' Shutdown and return a non-default exit code
Application.Current.Shutdown(-1)
// Shutdown and return a non-default exit code
Application.Current.Shutdown(-1);

Para detectar el valor del código de salida y cambiarlo, controle el evento Exit. Al controlador de eventos Exit se le pasa un objeto ExitEventArgs que proporciona acceso al código de salida con la propiedad ApplicationExitCode. Para obtener más información, vea Exit.

NotaNota

El código de salida puede establecerse tanto en las aplicaciones independientes como en las XBAPs.Sin embargo, el valor del código de salida se omite para las XBAPs.

Excepciones no controladas

A veces, puede que una aplicación se cierre en condiciones irregulares, como cuando se produce una excepción imprevista. En este caso, es posible que la aplicación no tenga el código necesario para detectar y procesar la excepción. Este tipo de excepción es una excepción no controlada; se muestra una notificación similar a la que aparece en la figura siguiente antes de que se cierre la aplicación.

Notificación de excepción no controlada

Desde la perspectiva del usuario, es mejor que una aplicación evite este comportamiento predeterminado realizando todas o alguna de las siguientes acciones:

  • Mostrar información fácil de usar.

  • Intentar mantener la aplicación en funcionamiento.

  • Registrar en el registro de eventos de Windows información detallada sobre la excepción que sea fácil de usar para el desarrollador.

La implementación de esta compatibilidad depende de la capacidad para detectar las excepciones no controladas; el evento DispatcherUnhandledException se provoca con esta finalidad.

<Application
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="SDKSample.App"
  StartupUri="MainWindow.xaml"
  DispatcherUnhandledException="App_DispatcherUnhandledException" />

Imports Microsoft.VisualBasic
Imports System.Windows ' Application
Imports System.Windows.Threading ' DispatcherUnhandledExceptionEventArgs

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
using System.Windows; // Application
using System.Windows.Threading; // DispatcherUnhandledExceptionEventArgs

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;
        }
    }
}

Al controlador de eventos DispatcherUnhandledException se le pasa un parámetro DispatcherUnhandledExceptionEventArgs que contiene información contextual referente a la excepción no controlada, incluida la propia excepción (DispatcherUnhandledExceptionEventArgs.Exception). Puede utilizar esta información para determinar cómo debe controlar la excepción.

Cuando controle DispatcherUnhandledException, establezca la propiedad DispatcherUnhandledExceptionEventArgs.Handled en true; de lo contrario, WPF seguirá considerando la excepción como no controlada y volverá al comportamiento predeterminado que se ha descrito anteriormente. Si se produce una excepción no controlada y no se controla el evento DispatcherUnhandledException, o bien, se controla el evento y se establece Handled en false, la aplicación se cerrará inmediatamente. Además, no se provocará ningún otro evento de Application. Por consiguiente, deberá controlar DispatcherUnhandledException si la aplicación tiene código que deba ejecutarse antes de que se cierre la aplicación.

Aunque es posible que una aplicación se cierre como resultado de una excepción no controlada, las aplicaciones suelen cerrarse en respuesta a una solicitud del usuario, tal como se explica en la sección siguiente.

Eventos de duración de la aplicación

Las aplicaciones independientes y las XBAPs no tienen exactamente la misma duración. En la ilustración siguiente se muestran los eventos clave en la duración de una aplicación independiente y la secuencia en la que se generan.

Aplicación independiente: Eventos de objetos de la aplicación

Igualmente, en la figura siguiente se muestran los eventos clave a lo largo de la duración de una aplicación XBAP y la secuencia en la que se provocan.

XBAP: Eventos de objetos de la aplicación

Otros servicios de aplicación

Además de administrar la duración de una aplicación, Application proporciona servicios entre los cuales figuran los siguientes:

  • Propiedades compartidas en el ámbito de la aplicación.

  • Recursos compartidos en el ámbito de la aplicación.

  • Archivos de recursos, de contenido y de sitio de origen de la aplicación.

  • Administración de ventanas.

  • Administración de la navegación.

Propiedades compartidas en el ámbito de la aplicación

La aplicación proporciona la propiedad Properties para exponer el estado que se puede compartir en toda la aplicación. A continuación se muestra un ejemplo de cómo usar Properties:

      ' Set an application-scope property with a custom type
      Dim customType As New CustomType()
      Application.Current.Properties("CustomType") = customType


...


      ' Get an application-scope property
      ' NOTE: Need to convert since Application.Properties is a dictionary of System.Object
      Dim customType As CustomType = CType(Application.Current.Properties("CustomType"), CustomType)
// Set an application-scope property with a custom type
CustomType customType = new CustomType();
Application.Current.Properties["CustomType"] = customType;


...


// Get an application-scope property
// NOTE: Need to convert since Application.Properties is a dictionary of System.Object
CustomType customType = (CustomType)Application.Current.Properties["CustomType"];

Para obtener más información, vea las secciones siguientes:

Recursos compartidos en el ámbito de la aplicación

La aplicación proporciona la propiedad Resources, que permite a los desarrolladores compartir los recursos de la UI en una aplicación. A continuación se muestra un ejemplo de cómo usar Resources:

      ' Set an application-scope resource
      Application.Current.Resources("ApplicationScopeResource") = Brushes.White


...


      ' Get an application-scope resource
      Dim whiteBrush As Brush = CType(Application.Current.Resources("ApplicationScopeResource"), Brush)
// Set an application-scope resource
Application.Current.Resources["ApplicationScopeResource"] = Brushes.White;


...


// Get an application-scope resource
Brush whiteBrush = (Brush)Application.Current.Resources["ApplicationScopeResource"];

Para obtener más información, vea las secciones siguientes:

Archivos de recursos, de contenido y de sitio de origen de la aplicación

Las aplicaciones WPF pueden administrar varios tipos de archivos de datos que no son de código, como los archivos de recursos, los archivos de contenido y los archivos de sitio de origen. Se pueden utilizar los siguientes métodos auxiliares para cargar estos tipos de archivos de datos:

Administración de ventanas

Application y Window tienen una relación estrecha. Como se ha mencionado anteriormente, la duración de una aplicación puede depender de la duración de sus ventanas, según lo especificado por la propiedad ShutdownMode. Application registra qué ventana se designa como ventana principal de la aplicación (Application.MainWindow), y mantiene una lista de las ventanas de las que se han creado instancias (Application.Windows).

Para obtener más información, vea Información general sobre ventanas de WPF.

Administración de la navegación

Para las aplicaciones independientes con navegación (que utilizan NavigationWindow y Frame) o XBAPs, Application detecta cualquier navegación dentro de una aplicación y provoca los siguientes eventos según corresponda:

Además, Application permite a las aplicaciones de cualquier tipo crear, conservar y recuperar cookies, mediante los métodos GetCookie y SetCookie.

Para obtener más información, vea Información general sobre navegación.

Vea también

Referencia

Application

Conceptos

Información general sobre ventanas de WPF

Información general sobre navegación

Archivos de recursos, contenido y datos de aplicaciones de WPF

Empaquetar URI en WPF

Desarrollo de aplicaciones

Otros recursos

Temas "Cómo..." del modelo de aplicaciones