En unos de mis proyectos que utilizo para entretenerme, activé el análisis de código del Visual Studio. Uno de los errores que me daba (Sí, los activé como errores, no como warnings :D) era el siguiente:
CA1704 : Microsoft.Naming : Correct the spelling of 'Invertis' in namespace name 'Sector7G.Invertis.YahooService'.
A la regla de CA1704 no le gustaba demasiado el nombre de mis Namespaces. Esto es debido a que Invertis no está dentro del diccionario que indica que esta palabra está escrita correctamente. La forma de arreglar este error es añadir Invertis dentro del diccionario.
El nuevo diccionario puede añadirse a nivel de proyecto o de solución. A mí me parece más correcto a nivel de solución, así puede ser compartido por todos los proyectos. Para ello hay que crear un nuevo archivo dentro de la solución, CodeAnalysisDictionary.xml por ejemplo. En las propiedades del archivo marcar Build Action cómo CodeAnalysisDictionary. El formato de este archivo es el siguiente:
<?xml version="1.0" encoding="utf-8"?>
<Dictionary>
<Words>
<Recognized>
<Word>Invertis</Word>
<Word>Sector7G</Word>
</Recognized>
</Words>
</Dictionary>
Para poder usar este diccionarios desde los diferentes proyectos, sólo hay que añadirlo como enlace (Añadir nuevo elemento / seleccionar elemento / añadir como enlace) a cada proyecto. También hay que asegurarse de que su Build Action esté establecida a CodeAnalysisDictionary.
De esta forma ya es posible compilar sin ningún problema.
Con la llegada del Visual Studio 2008 SP1, se ha introducido la clase SplashScreen. Esta clase permite de una forma sencilla, dos líneas de código, crear un Splash Screen haciendo uso de una imagen.
Para utilizar esta clase, el primer paso es añadir una imagen al proyecto. A esta imagen se la debe de asignar la propiedad Build Action a Resource (botón derecho sobre la imagen -> propiedades). En el ejemplo, la imagen se encuentra ubicada en un assembly diferente.
Dentro del constructor de la clase App situada en el archivo App.xaml.cs, situaremos el código necesario para hacer que el Splash Screen se muestre.
Assembly assm = Assembly.Load("Sector7G.Invertis.Wpf.Skins");
SplashScreen splashScreen = new SplashScreen(assm, @"Images\SplashScreen.png");
splashScreen.Show(false);
El método Show acepta como parámetro un booleano. Si es true, el Splash Screen se cerrará automáticamente el sólo, después de 300 milesegudos. Si el valor es false, entonces hasta que no se haga una llamada al método Close el Splash Screen no se cerrará.
Una vez hecho esto, ya se puede hacer una llamada al método Run del Bootstrapper, para que empiece a cargar toda la aplicación.
Bootstrapper bootStrapper = new Bootstrapper();
bootStrapper.Run();
Dentro del Bootstrapper hay que hacer una modificación en el método CreateShell. En este método se crea y se registra dentro del Container el Shell y es donde se hacer el Show de la aplicación. Así que lo que hay que hacer, es no realizar el Show en este punto. El Show debe hacerse dentro del handler al evento Startup de la clase App. Este será lanzado cuando la aplicación se haya cargado completamente.
protected override DependencyObject CreateShell()
{
Shell shell = new Shell();
Container.RegisterInstance<Shell>(shell);
return shell;
}
Dentro de la clase App, cuando el evento Startup se lanza, hay que cerrar el Splash y mostrar la aplicación.
private void Application_Startup(object sender, StartupEventArgs e)
{
splashScreen.Close(TimeSpan.FromMilliseconds(0));
Shell shell = bootStrapper.Container.Resolve<Shell>();
shell.Show();
}
El método Close de la clase SplashScreen acepta como parámetro un valor del tipo TimeSpan. Con ello, se le indica el tiempo que debe de mostrarse. En este caso, como ya sabemos que la aplicación se ha cargado completamente, no hace falta que se muestre más. Por ello, se le indica un TimeSpan de cero.
Si por algún motivo dentro de una aplicación es lanzada una excepción que no es capturada. Esta excepción provocará que la aplicación falle y se cierre automáticamente.
Las aplicaciones desarrolladas en WPF provén una forma de evitar este comportamiento. Para ello, dentro del App.xaml hay que hacer uso del evento DispatcherUnhandledException. Este evento se encargará de capturar todas aquellas excepciones no manejadas. Esto nos permitirá de esta forma gestionar posteriormente la excepción. Como por ejemplo, mostrando un mensaje al usuario.
<Application x:Uid="Application_1"
x:Class="Sector7G.Invertis.Wpf.Shell.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DispatcherUnhandledException="Application_DispatcherUnhandledException">
</Application>
El evento DispatcherUnhandledException contiene un parámetro del tipo DispatcherUnhandledExceptionEventArgs. Este parámetro contiene toda la información sobre la excepción no capturada. Con esta información ya se puede decidir cómo tratar la excepción dependiendo del tipo que sea.
private void Application_DispatcherUnhandledException(object sender,
DispatcherUnhandledExceptionEventArgs e)
{
MessageBox.Show(e.Exception.Message);
e.Handled = true;
}
Si la excepción puede ser tratada correctamente hay que indicar que la excepción ha sido manejada finalmente (e.Handled = true;). Si no se indica, la excepción se tomará como no manejada y la aplicación se cerrara.