Ventanas modales en Silverlight

Martes, 03 feb, 2009 @ 21:54 | Por Gustavo Cantero (The Wolf) | Silverlight

En Silverlight, como es sabido, no se pueden crear ventanas modales, por lo cual vamos a mostrar como simular esta funcionalidad utilizando un Popup.

El Popup es un objeto del framework de Silverlight 2 que permite mostrar el contenido de un elemento sobre el resto. Con esto podríamos simular la ventana que queremos crear, pero tenemos el problema que alrededor de esta ventana se puede cliquear e interactuar con los elementos que están “por debajo” de ésta. Para evitar esto lo que haremos es crear un elemento “Border” que ocupe toda la página de Silverlight, el cual debe tener un fondo para evitar que el usuario pulse sobre los elementos que están por debajo. Para el fondo podemos utilizar, por ejemplo, el objeto SolidColorBrush con el color negro y una opacidad de 20, para que se pueda ver a través él (si no queremos que se grisee esta zona se puede utilizar el color Colors.Transparent).

El siguiente inconveniente que si el control de Silverlight ocupa un porcentaje de la ventana del navegador (o sea, no tiene un tamaño fijo) y el usuario modifica el tamaño del browser, la sección griseada de la ventana debería modificarse para seguir ocupando el cien por ciento de la página. Para solucionar esto se puede manejar el evento Resized del objeto Application.Current.Host.Content, estableciendo ahí el tamaño del borde del Popup al tamaño actual del objeto Application.Current.RootVisual.

Por último, también tenemos el problema de que, si al Popup le agregamos elementos como un ListBox que tiene interacción con el usuario y necesitamos manejar sus eventos, el Silverlight nos devolverá un error. Para evitar esto simplemente tenemos que agregar el Popup al elemento raíz de nuestra página y, al cerrarlo, quitarlo.

A continuación muestro el código de un método estático

/// <summary>
/// Muestra un objeto en una ventana modal simulada a través de un <see cref="Popup"/>
/// </summary>
/// <param name="Content">Contenido a mostrar en la ventana</param>
public static Popup Show(UIElement Content)
{
    //Botón "cerrar"
    Button btnClose = new Button();
    btnClose.Content = new TextBlock() { Text = "Cerrar" };
    btnClose.HorizontalAlignment = HorizontalAlignment.Center;
    btnClose.Margin = new Thickness(0, 10, 0, 0);

    //Grilla para ubicar el contenido y el botón
    Grid objGridContent = new Grid();
    objGridContent.RowDefinitions.Add(new RowDefinition());
    objGridContent.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
    objGridContent.Children.Add(Content);
    objGridContent.Children.Add(btnClose);
    Grid.SetRow(btnClose, 1);

    //Borde de la ventana
    Border objPopupBorder = new Border();
    objPopupBorder.CornerRadius = new CornerRadius(10);
    objPopupBorder.Background = new SolidColorBrush(Colors.White);
    objPopupBorder.BorderThickness = new Thickness(2);
    objPopupBorder.BorderBrush = new SolidColorBrush(Color.FromArgb(255, 128, 128, 128));
    objPopupBorder.Child = objGridContent;
    objPopupBorder.Padding = new Thickness(10);
    objPopupBorder.Margin = new Thickness(20);
    objPopupBorder.HorizontalAlignment = HorizontalAlignment.Center;
    objPopupBorder.VerticalAlignment = VerticalAlignment.Center;

    //Fondo de la ventana
    Border objBackBorder = new Border();
    objBackBorder.Width = Application.Current.RootVisual.RenderSize.Width;
    objBackBorder.Height = Application.Current.RootVisual.RenderSize.Height;
    objBackBorder.Background = new SolidColorBrush(Color.FromArgb(70, 0, 0, 0));
    objBackBorder.Opacity = 1;
    objBackBorder.Child = objPopupBorder;

    //Popup
    Popup objPopup = new Popup();
    objPopup.Child = objBackBorder;
    ((Application.Current.RootVisual as UserControl).FindName("LayoutRoot") as Grid).Children.Add(objPopup);
    objPopup.Closed += delegate(object sender, EventArgs e)
    {
        //Saco el popup de la grilla
        UIElementCollection objRootElements = ((Application.Current.RootVisual as UserControl).FindName("LayoutRoot") as Grid).Children;
        if (objRootElements.Contains(objPopup))
            objRootElements.Remove(objPopup);
    };
    objPopup.IsOpen = true;

    //Cerramos el popup al pulsar en el botón
    btnClose.Click += delegate(object sender2, RoutedEventArgs e2) { objPopup.IsOpen = false; };

    //Cambio el tamaño del fondo cuando cambia de tamaño el control
    Application.Current.Host.Content.Resized += delegate(object sender, EventArgs e)
    {
        objBackBorder.Width = Application.Current.RootVisual.RenderSize.Width;
        objBackBorder.Height = Application.Current.RootVisual.RenderSize.Height;
    };

    return objPopup;
}

Como siempre, les dejo un proyecto con este código funcionando para que lo prueben. Proyecto de ejemplo de Popup Modal en Silverlight

VN:F [1.7.3_972]
Rating: 8.0/10 (12 votos cast)

Reciente

  • Discurso de Steve Jobs
  • Llamar a métodos de una página ASP.NET desde JavaScript con jQuery
  • Compartir en Facebook desde nuestra aplicación web
  • Migrar de Google Maps v2 a Google Maps v3
  • Obtener identificador único de dispositivo con Android
  • La psicología del color
  • Geolocalización con HTML 5
  • Cómo firmar un documento PDF desde C# con iTextSharp
  • Obtener lista de contactos de Gmail
  • Pósters de tecnologías y productos de Microsoft
  •  

    Una Respuesta a “Ventanas modales en Silverlight”

      tavo tavo dijo:

      hola me parece un codigo muy servicial

      VA:F [1.7.3_972]
      Rating: 0.0/5 (0 votos cast)

    Responder

    XHTML: Puede utilizar estos tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>