Información general sobre ventanas de WPF

Los usuarios interactúan con las aplicaciones independientes de Windows Presentation Foundation (WPF) por medio de ventanas. El propósito principal de una ventana es hospedar contenido que permita visualizar datos y que permita a los usuarios interactuar con estos. Las aplicaciones independientes de WPF proporcionan sus propias ventanas mediante la clase Window. Este tema presenta Window antes de tratar los principios fundamentales de creación y administración de ventanas en las aplicaciones independientes.

Nota:

Las aplicaciones WPF hospedadas en el explorador, incluidas las aplicaciones de explorador XAML (XBAP) y las páginas de lenguaje XAML, no proporcionan sus propias ventanas. En su lugar, se hospedan en ventanas proporcionadas por Windows Internet Explorer. Consulte Información general sobre las aplicaciones de explorador XAML de WPF.

Clase de la ventana

En la figura siguiente se muestran los elementos que componen una ventana:

Captura de pantalla que muestra elementos de ventana.

Una ventana se divide en dos áreas: el área distinta del cliente y el área cliente.

WPF implementa el área no cliente de una ventana e incluye los elementos que son comunes a la mayoría de las ventanas, incluidos los siguientes:

  • Un borde.

  • Una barra de título.

  • Un icono.

  • Botones Minimizar, Maximizar y Restaurar.

  • Un botón Cerrar.

  • Un menú de sistema con elementos de menú que permiten a los usuarios minimizar, maximizar, restaurar, mover, cambiar el tamaño y cerrar una ventana.

El área cliente de una ventana es el área dentro de su área no de cliente que utilizan los desarrolladores para agregar contenido específico de la aplicación, como barras de menús, barras de herramientas y controles.

En WPF, una ventana está encapsulada por la clase Window que se usa para lo siguiente:

  • Mostrar una ventana.

  • Configurar el tamaño, posición y aspecto de una ventana.

  • Hospedar contenido específico de la aplicación.

  • Administrar la duración de una ventana.

Implementar una ventana

La implementación de una ventana típica consta de apariencia y comportamiento, donde apariencia define el aspecto de una ventana para los usuarios y comportamiento define la forma en que funciona una ventana cuando los usuarios interactúan con ella. En WPF, puede implementar la apariencia y el comportamiento de una ventana mediante código o marcado XAML.

Pero en general, la apariencia de una ventana se implementa mediante marcado XAML y su comportamiento se implementa mediante código subyacente, como se muestra en el ejemplo siguiente.

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.MarkupAndCodeBehindWindow">
  
  <!-- Client area (for content) -->
  
</Window>
using System.Windows;

namespace SDKSample
{
    public partial class MarkupAndCodeBehindWindow : Window
    {
        public MarkupAndCodeBehindWindow()
        {
            InitializeComponent();
        }
    }
}

Imports System.Windows

Namespace SDKSample
    Partial Public Class MarkupAndCodeBehindWindow
        Inherits Window
        Public Sub New()
            InitializeComponent()
        End Sub
    End Class
End Namespace

Para que un archivo de marcado XAML y uno de código subyacente funcionen de manera conjunta, se necesita lo siguiente:

  • En el marcado, el elemento Window debe incluir el atributo x:Class. Cuando se compila la aplicación, la existencia de x:Class en el archivo de marcación provoca que Microsoft Build Engine (MSBuild) cree una clase partial que deriva de Window y tiene el nombre especificado por el atributo x:Class. Para esto es necesario agregar una declaración de espacio de nombres XML para el esquema XAML (xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"). La clase partial generada implementa el método InitializeComponent, que se llama para registrar los eventos y establecer las propiedades que se implementan en el marcado.

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

  • En el código subyacente, la clase Window debe implementar un constructor que llame al método InitializeComponent. InitializeComponent se implementa mediante la clase partial generada por el archivo de marcado para registrar eventos y establecer las propiedades que se definen en el marcado.

Nota

Cuando se agrega una nueva instancia de Window al proyecto con Visual Studio, se implementa Windowmediante el marcado y el código subyacente, y se incluye la configuración necesaria para crear la asociación entre los archivos de marcado y código subyacente, como se describe aquí.

Después de agregar esta configuración, puede centrarse en definir el aspecto de la ventana en el marcado XAML e implementar su comportamiento en el código subyacente. En el ejemplo siguiente se muestra una ventana con un botón, implementado en la marcación XAML y un controlador de eventos para el evento Click del botón, implementado mediante código subyacente.

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.MarkupAndCodeBehindWindow">
  <!-- Client area (for content) -->
  <Button Click="button_Click">Click This Button</Button>
</Window>
using System.Windows;

namespace SDKSample
{
    public partial class MarkupAndCodeBehindWindow : Window
    {
        public MarkupAndCodeBehindWindow()
        {
            InitializeComponent();
        }

        void button_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("Button was clicked.");
        }
    }
}

Imports System.Windows

Namespace SDKSample
    Partial Public Class MarkupAndCodeBehindWindow
        Inherits Window
        Public Sub New()
            InitializeComponent()
        End Sub

        Private Sub button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
            MessageBox.Show("Button was clicked.")
        End Sub
    End Class
End Namespace

Configuración de una definición de ventana para MSBuild

La forma de implementar la ventana determina cómo se configura para MSBuild. Para una ventana que se define mediante marcado XAML y código subyacente:

  • Los archivos de marcado XAML se configuran como elementos Page de MSBuild.

  • Los archivos de código subyacente se configuran como elementos Compile de MSBuild.

Esta implementación se muestra en el archivo de proyecto MSBuild siguiente.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ... >  
    ...  
    <Page Include="MarkupAndCodeBehindWindow.xaml" />  
    <Compile Include=" MarkupAndCodeBehindWindow.xaml.cs" />  
    ...  
</Project>  

Para más información sobre la compilación de aplicaciones WPF, consulte Compilar una aplicación de WPF.

Duración de ventana

Como cualquier clase, una ventana tiene una vigencia que comienza cuando se crea una instancia por primera vez, después de lo cual se abre, activa y desactiva y, finalmente, se cierra.

Abrir una ventana

Para abrir una ventana, primero hay que crear una instancia de esta, como se muestra en el ejemplo siguiente.

<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">
</Application>
using System.Windows;
namespace SDKSample
{
    public partial class App : Application
    {
        void app_Startup(object sender, StartupEventArgs e)
        {
            // Create a window
            MarkupAndCodeBehindWindow window = new MarkupAndCodeBehindWindow();

            // Open a window
            window.Show();
        }
    }
}

En este ejemplo, se crea la instancia de MarkupAndCodeBehindWindow cuando se inicia la aplicación, lo que se produce cuando se genera el evento Startup.

Cuando se crea una instancia de una ventana, de forma automática se agrega una referencia a ella a una lista de ventanas administrada por el objeto Application (consulte Application.Windows). Además, la primera ventana de la que se crea una instancia se establece, de forma predeterminada, mediante Application como la ventana principal de la aplicación (consulte Application.MainWindow).

La ventana se abre finalmente llamando al método Show. El resultado se muestra en la ilustración siguiente.

Ventana abierta mediante una llamada a Window.Show

Una ventana que se abre mediante la llamada a Show es una ventana no modal, lo que significa que la aplicación funciona en un modo que permite a los usuarios activar otras ventanas en la misma aplicación.

Nota:

Se llama a ShowDialog para abrir ventanas como cuadros de diálogo de forma modal. Para más información, consulte Información general sobre cuadros de diálogo.

Cuando se llama a Show, una ventana realiza el trabajo de inicialización antes de mostrarse para establecer la infraestructura que le permite recibir entradas del usuario. Cuando la ventana se inicializa, se genera el evento SourceInitialized y se muestra la ventana.

Como método abreviado, se puede establecer StartupUri para especificar la primera ventana que se abre automáticamente cuando se inicia una aplicación.

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

Cuando se inicia la aplicación, la ventana especificada por el valor de StartupUri se abre forma no modal; internamente, la ventana se abre llamando al método Show.

Propiedad de la ventana

Una ventana que se abre mediante el método Show no tiene ninguna relación implícita con la ventana que la creó; los usuarios pueden interactuar con cualquier ventana independientemente de la otra, lo que significa que cualquier ventana puede hacer lo siguiente:

  • Superponerse a la otra (a menos que en una de las ventanas la propiedad Topmost esté establecida en true).

  • Minimizarse, maximizarse y restaurarse sin que afecte a las demás.

Algunas ventanas requieren una relación con la ventana que las abre. Por ejemplo, una aplicación de entorno de desarrollo integrado (IDE) puede abrir ventanas de propiedades y de herramientas cuyo comportamiento típico es superponerse sobre la ventana que las crea. Además, dichas ventanas se deben siempre cerrar, minimizar, maximizar y restaurar de acuerdo con la ventana que las creó. Este tipo de relación se puede establecer haciendo que una ventana posea otra, lo que se logra al establecer la propiedad Owner de la ventana poseída con una referencia a la ventana propietaria. Esto se muestra en el ejemplo siguiente.

// Create a window and make this window its owner
Window ownedWindow = new Window();
ownedWindow.Owner = this;
ownedWindow.Show();
' Create a window and make this window its owner
Dim ownedWindow As New Window()
ownedWindow.Owner = Me
ownedWindow.Show()

Una vez establecida la propiedad:

  • La ventana poseída puede hacer referencia a la ventana propietaria mediante la inspección del valor de su propiedad Owner.

  • La ventana propietaria puede descubrir todas las ventanas que posee mediante la inspección del valor de su propiedad OwnedWindows.

Prevención de la activación de ventanas

Hay escenarios en los que las ventanas no se deben activar cuando se muestran como, por ejemplo, ventanas de conversación de una aplicación de mensajería de Internet o ventanas de notificación de una aplicación de correo electrónico.

Si la aplicación tiene una ventana que no se debería activar cuando se muestra, puede establecer su propiedad ShowActivated en false antes de llamar al método Show por primera vez. Como resultado:

  • La ventana no está activada.

  • El evento Activated de la ventana no se genera.

  • La ventana actualmente activada permanece activada.

Sin embargo, la ventana se activará tan pronto como el usuario la active haciendo clic en el área de cliente o en el área distinta del cliente. En este caso:

  • La ventana se activa.

  • Se genera el evento Activated de la ventana.

  • La ventana activada previamente se desactiva.

  • Los eventos Deactivated y Activated se generan posteriormente como es previsible en respuesta a las acciones del usuario.

Activación de ventanas

Cuando se abre una ventana por primera vez, se convierte en la ventana activa (a menos que aparezca con ShowActivated establecido en false). La ventana activa es la que captura actualmente la entrada de usuario, como, por ejemplo, pulsaciones de teclas y clics del mouse. Cuando una ventana se convierte en la activa, genera el evento Activated.

Nota

Cuando se abre una ventana por primera vez, los eventos Loaded y ContentRendered solo se generan después de que se genere el evento Activated. Teniendo esto en cuenta, una ventana se puede considerar efectivamente abierta cuando se genera ContentRendered.

Después de que se activa una ventana, un usuario puede activar otra ventana de la misma aplicación o activar otra aplicación. Cuando esto ocurre, la ventana activa actualmente se desactiva y genera el evento Deactivated. Igualmente, cuando el usuario selecciona una ventana actualmente desactivada, la ventana se volverá a activar y se genera Activated.

Un motivo habitual de controlar Activated y Deactivated es para habilitar y deshabilitar funciones que solo se pueden ejecutar cuando una ventana está activa. Por ejemplo, algunas ventanas muestran contenido interactivo que requiere la entrada o atención del usuario constante, incluidos los reproductores de vídeo y los juegos. El ejemplo siguiente es un reproductor de vídeo simplificado que muestra cómo controlar Activated y Deactivated para implementar este comportamiento.

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.CustomMediaPlayerWindow"
    Activated="window_Activated"
    Deactivated="window_Deactivated">

    <!-- Media Player -->
    <MediaElement 
      Name="mediaElement" 
      Stretch="Fill" 
      LoadedBehavior="Manual" 
      Source="numbers.wmv" />

</Window>
using System;
using System.Windows;

namespace SDKSample
{
    public partial class CustomMediaPlayerWindow : Window
    {
        public CustomMediaPlayerWindow()
        {
            InitializeComponent();
        }

        void window_Activated(object sender, EventArgs e)
        {
            // Recommence playing media if window is activated
            this.mediaElement.Play();
        }

        void window_Deactivated(object sender, EventArgs e)
        {
            // Pause playing if media is being played and window is deactivated
            this.mediaElement.Pause();
        }
    }
}

Imports System.Windows

Namespace SDKSample
    Partial Public Class CustomMediaPlayerWindow
        Inherits Window
        Public Sub New()
            InitializeComponent()
        End Sub

        Private Sub window_Activated(ByVal sender As Object, ByVal e As EventArgs)
            ' Recommence playing media if window is activated
            Me.mediaElement.Play()
        End Sub

        Private Sub window_Deactivated(ByVal sender As Object, ByVal e As EventArgs)
            ' Pause playing if media is being played and window is deactivated
            Me.mediaElement.Pause()
        End Sub
    End Class
End Namespace

Cuando se desactiva una ventana, otros tipos de aplicaciones pueden ejecutar código en segundo plano. Por ejemplo, un cliente de correo puede continuar sondeando el servidor de correo electrónico mientras el usuario está utilizando otras aplicaciones. Las aplicaciones como estas suelen ofrecen un comportamiento diferente o adicional mientras la ventana principal está desactivada. Con respecto al programa de correo electrónico, esto puede significar agregar el nuevo elemento de correo a la bandeja de entrada o agregar un icono de notificación a la bandeja del sistema. Solamente es necesario mostrar un icono de notificación cuando la ventana de correo no está activa, lo cual se puede determinar inspeccionando la propiedad IsActive.

Si se completa una tarea en segundo plano, es posible que una ventana quiera notificar al usuario de manera más urgente mediante una llamada al método Activate. Si el usuario interactúa con otra aplicación activada cuando se llama a Activate, el botón de la barra de tareas de la ventana parpadeará. Si un usuario está interactuando con la aplicación actual, la llamada a Activate hará que aparezca la ventana en primer plano.

Nota

Puede controlar la activación con ámbito de aplicación por medio de los eventos Application.Activated y Application.Deactivated.

Cerrar una ventana

La vigencia de una ventana llega a su fin cuando un usuario la cierra. Se puede cerrar una ventana mediante elementos del área distinta del cliente, entre los que cabe incluir los siguientes:

  • El elemento Cerrar del menú Sistema.

  • Presionar ALT+F4.

  • Presionar el botón Cerrar.

Puede proporcionar mecanismos adicionales al área cliente para cerrar una ventana. Entre los más habituales se incluyen los siguientes:

  • Un elemento Salir en el menú Archivo, normalmente para las ventanas de la aplicación principal.

  • Un elemento Cerrar en el menú Archivo, normalmente para las ventanas de una aplicación secundaria.

  • Un botón Cancelar, normalmente en un cuadro de diálogo modal.

  • Un botón Cerrar, normalmente en un cuadro de diálogo sin modo.

Para cerrar una ventana en respuesta a uno de estos mecanismos personalizados, debe llamar al método Close. En el ejemplo siguiente se implementa la capacidad de cerrar una ventana mediante la elección del elemento Salir del menú Archivo.

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.WindowWithFileExit">
  
  <Menu>
    <MenuItem Header="_File">
      <MenuItem Header="E_xit" Click="fileExitMenuItem_Click" />
    </MenuItem>
  </Menu>
  
</Window>
using System.Windows;

namespace SDKSample
{
    public partial class WindowWithFileExit : System.Windows.Window
    {
        public WindowWithFileExit()
        {
            InitializeComponent();
        }

        void fileExitMenuItem_Click(object sender, RoutedEventArgs e)
        {
            // Close this window
            this.Close();
        }
    }
}

Imports System.Windows

Namespace SDKSample
    Partial Public Class WindowWithFileExit
        Inherits System.Windows.Window
        Public Sub New()
            InitializeComponent()
        End Sub

        Private Sub fileExitMenuItem_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
            ' Close this window
            Me.Close()
        End Sub
    End Class
End Namespace

Cuando se cierra una ventana, genera dos eventos: Closing y Closed.

Closing se genera antes de que se cierre la ventana y proporciona un mecanismo por el que se puede impedir el cierre de la ventana. Una razón común para evitar el cierre de la ventana se produce en caso de que el contenido de la ventana contenga datos modificados. En esta situación, el evento Closing se puede controlar para determinar si los datos se han modificado y, en ese caso, preguntar al usuario si quiere continuar con el cierre de la ventana sin guardar los datos o cancelar el cierre. En el ejemplo siguiente se muestran los aspectos clave del control de Closing.

using System; // EventArgs
using System.ComponentModel; // CancelEventArgs
using System.Windows; // window

namespace CSharp
{
    public partial class DataWindow : Window
    {
        // Is data dirty
        bool isDataDirty = false;

        public DataWindow()
        {
            InitializeComponent();
        }

        void documentTextBox_TextChanged(object sender, EventArgs e)
        {
            this.isDataDirty = true;
        }

        void DataWindow_Closing(object sender, CancelEventArgs e)
        {
            MessageBox.Show("Closing called");

            // If data is dirty, notify user and ask for a response
            if (this.isDataDirty)
            {
                string msg = "Data is dirty. Close without saving?";
                MessageBoxResult result =
                  MessageBox.Show(
                    msg,
                    "Data App",
                    MessageBoxButton.YesNo,
                    MessageBoxImage.Warning);
                if (result == MessageBoxResult.No)
                {
                    // If user doesn't want to close, cancel closure
                    e.Cancel = true;
                }
            }
        }
    }
}
Imports System ' EventArgs
Imports System.ComponentModel ' CancelEventArgs
Imports System.Windows ' window

Namespace VisualBasic
    Partial Public Class DataWindow
        Inherits Window
        ' Is data dirty
        Private isDataDirty As Boolean = False

        Public Sub New()
            InitializeComponent()
        End Sub

        Private Sub documentTextBox_TextChanged(ByVal sender As Object, ByVal e As EventArgs)
            Me.isDataDirty = True
        End Sub

        Private Sub DataWindow_Closing(ByVal sender As Object, ByVal e As CancelEventArgs)
            MessageBox.Show("Closing called")

            ' If data is dirty, notify user and ask for a response
            If Me.isDataDirty Then
                Dim msg As String = "Data is dirty. Close without saving?"
                Dim result As MessageBoxResult = MessageBox.Show(msg, "Data App", MessageBoxButton.YesNo, MessageBoxImage.Warning)
                If result = MessageBoxResult.No Then
                    ' If user doesn't want to close, cancel closure
                    e.Cancel = True
                End If
            End If
        End Sub
    End Class
End Namespace

Al controlador de eventos Closing se le pasa un objeto CancelEventArgs, que implementa la propiedad BooleanCancel establecida en true para evitar que se cierre una ventana.

Si no se administra Closing, o se administra pero no se cancela, la ventana se cerrará. Justo antes de que se cierre una ventana, se genera Closed. En este momento, ya no se puede impedir el cierre de la ventana.

Nota

Se puede configurar una aplicación para que se cierre automáticamente cuando se cierra la ventana de la aplicación principal (vea MainWindow) o cuando se cierre la última ventana. Para obtener información detallada, vea ShutdownMode.

Aunque una ventana se puede cerrar de forma explícita mediante los mecanismos proporcionados en las áreas cliente y no cliente, también se puede cerrar de forma implícita como resultado de un comportamiento en otras partes de la aplicación o Windows, incluido lo siguiente:

  • Un usuario cierra la sesión o apaga Windows.

  • Un propietario de la ventana la cierra (consulte Owner).

  • Se cierra la ventana principal de la aplicación y ShutdownMode es OnMainWindowClose.

  • Se llama a Shutdown.

Nota:

No se puede volver a abrir una ventana cuando se ha cerrado.

Eventos de vigencia de ventanas

En la ilustración siguiente se muestra la secuencia de eventos principales en la vigencia de una ventana:

Diagrama en el que se muestran los eventos de la vigencia de una ventana.

En la ilustración siguiente se muestra la secuencia de eventos principales de la vigencia de una ventana que aparece sin activación (ShowActivated se establece en false antes de mostrar la ventana):

Diagrama en el que se muestran los eventos de la vigencia de una ventana sin activación.

Ubicación de la ventana

Mientras una ventana está abierta, tiene una ubicación en las dimensiones x e y en relación con el escritorio. Esta ubicación se puede determinar mediante la inspección de las propiedades Left y Top, respectivamente. Puede establecer estas propiedades para cambiar la ubicación de la ventana.

También puede especificar la ubicación inicial de una instancia de Window cuando aparezca por primera vez si establece la propiedad WindowStartupLocation con uno de los valores siguientes de la enumeración WindowStartupLocation:

Si se especifica la ubicación de inicio como Manual y no se han establecido las propiedades Left y Top, Window le preguntará a Windows una ubicación en la que aparecer.

Ventanas de nivel superior y orden Z

Además de tener una ubicación x e y, una ventana también tiene una ubicación en la dimensión z, que determina su posición vertical con respecto a otras ventanas. Esto se conoce como el orden z de la ventana y hay dos tipos: orden z normal y orden z superior. La ubicación de una ventana en el orden z normal depende de si está actualmente activa o no. De forma predeterminada, una ventana se encuentra en el orden z normal. La ubicación de una ventana en el orden z superior también depende de si está actualmente activa o no. Además, las ventanas del orden z superior siempre se encuentran por encima de aquellas del orden z normal. Una ventana se ubica en el orden z superior si se establece su propiedad Topmost en true.

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    Topmost="True">
</Window>

Dentro de cada orden z, la ventana actualmente activa aparece encima de las demás ventanas del mismo orden z.

Tamaño de ventana

Además de tener una ubicación en el escritorio, una ventana tiene un tamaño determinado por varias propiedades, entre las que se incluyen las diversas propiedades de ancho y alto, y SizeToContent.

MinWidth, Width y MaxWidth se utilizan para administrar el intervalo de anchuras que una ventana puede tener durante su vigencia y se configuran como se muestra en el ejemplo siguiente.

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    MinWidth="300" Width="400" MaxWidth="500">
</Window>

La altura de la ventana se administra mediante MinHeight, Height y MaxHeight, y se configura como se muestra en el ejemplo siguiente.

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    MinHeight="300" Height="400" MaxHeight="500">
</Window>

Dado que los distintos valores de anchura y altura especifican cada uno de ellos un intervalo, es posible que la anchura y altura de una ventana de tamaño ajustable se encuentre dentro del intervalo especificado para la dimensión correspondiente. Para detectar su ancho y alto actuales, inspeccione ActualWidth y ActualHeight, respectivamente.

Si prefiere que el ancho y el alto de la ventana tengan un tamaño que se ajuste al de su contenido, puede usar la propiedad SizeToContent, que tiene los valores siguientes:

  • Manual. Ningún efecto (valor predeterminado).

  • Width. Se ajusta al ancho del contenido, lo que tiene el mismo efecto que establecer MinWidth y MaxWidth en el ancho del contenido.

  • Height. Se ajusta al alto del contenido, lo que tiene el mismo efecto que establecer MinHeight y MaxHeight en el alto del contenido.

  • WidthAndHeight. Se ajusta al ancho y alto del contenido, lo que tiene el mismo efecto que establecer MinHeight y MaxHeight en el alto del contenido, y establecer MinWidth y MaxWidth en el ancho del contenido.

En el ejemplo siguiente se muestra una ventana que se redimensiona automáticamente para ajustarse al contenido, tanto vertical como horizontalmente, cuando se muestra por primera vez.

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    SizeToContent="WidthAndHeight">
</Window>

En el ejemplo siguiente se muestra cómo establecer la propiedad SizeToContent en el código para especificar cómo se cambia de tamaño una ventana para ajustarse al contenido.


// Manually alter window height and width
this.SizeToContent = SizeToContent.Manual;

// Automatically resize width relative to content
this.SizeToContent = SizeToContent.Width;

// Automatically resize height relative to content
this.SizeToContent = SizeToContent.Height;

// Automatically resize height and width relative to content
this.SizeToContent = SizeToContent.WidthAndHeight;

' Manually alter window height and width
Me.SizeToContent = SizeToContent.Manual

' Automatically resize width relative to content
Me.SizeToContent = SizeToContent.Width

' Automatically resize height relative to content
Me.SizeToContent = SizeToContent.Height

' Automatically resize height and width relative to content
Me.SizeToContent = SizeToContent.WidthAndHeight

Orden de prioridad de las propiedades de tamaño

Esencialmente, las diversas propiedades de tamaño de una ventana se combinan para definir el intervalo de anchura y altura de una ventana de tamaño ajustable. Para asegurarse de que se mantiene un intervalo válido, Window evalúa los valores de las propiedades de tamaño mediante los siguientes órdenes de prioridad.

Para las propiedades de altura:

  1. FrameworkElement.MinHeight

  2. FrameworkElement.MaxHeight

  3. SizeToContent.Height/SizeToContent.WidthAndHeight

  4. FrameworkElement.Height

Para las propiedades de anchura:

  1. FrameworkElement.MinWidth

  2. FrameworkElement.MaxWidth

  3. SizeToContent.Width/SizeToContent.WidthAndHeight

  4. FrameworkElement.Width

El orden de prioridad también puede determinar el tamaño de una ventana cuando se maximiza, lo cual se puede administrar con la propiedad WindowState.

Estado de la ventana

Durante la vigencia de una ventana de tamaño ajustable, esta puede tener tres estados: normal, minimizado y maximizado. Una ventana con un estado normal es el estado predeterminado. Una ventana con este estado permite al usuario moverla y cambiar su tamaño mediante los controles de cambio de tamaño o el borde, si es de tamaño ajustable.

Una ventana con un estado minimizado se contrae a su botón de la barra de tareas si ShowInTaskbar se establece en true; de lo contrario, se contrae al tamaño más pequeño posible y se desplaza a la esquina inferior izquierda del escritorio. Ningún tipo de ventana minimizada puede cambiar de tamaño mediante el borde ni mediante los controles de cambio de tamaño, aunque si no aparece en la barra de tareas se podrá arrastrar a cualquier parte del escritorio.

Una ventana con un estado maximizado se expande hasta el tamaño máximo posible, en función del que determinen las propiedades MaxWidth, MaxHeight y SizeToContent. Al igual que una ventana minimizada, no puede cambiarse el tamaño de una ventana maximizada mediante un control de cambio de tamaño ni arrastrando el borde.

Nota

Los valores de las propiedades Top, Left, Width y Height de una ventana siempre representan los valores para el estado normal, incluso cuando la ventana está maximizada o minimizada actualmente.

El estado de una ventana se puede configurar si se establece su propiedad WindowState, que puede tener uno de los valores siguientes de la enumeración WindowState:

En el ejemplo siguiente se muestra cómo crear una ventana que se muestra como maximizada cuando se abre.

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    WindowState="Maximized">
</Window>

En general, debe establecer WindowState para configurar el estado inicial de una ventana. Cuando aparece una ventana de tamaño ajustable, los usuarios pueden presionar los botones para minimizar, maximizar y restaurar situados en la barra de título de la ventana para cambiar el estado de esta.

Aspecto de la ventana

Puede cambiar el aspecto del área cliente de una ventana mediante la adición de contenido específico, como botones, etiquetas y cuadros de texto. Para configurar el área no cliente, Window proporciona varias propiedades, entre las que se incluyen Icon para establecer el icono de una ventana y Title para establecer su título.

También puede cambiar el aspecto y comportamiento del borde del área distinta del cliente configurando el modo de cambio de tamaño de la ventana, el estilo de esta y si aparece como un botón en la barra de tareas del escritorio.

Modo de cambio de tamaño

Dependiendo de la propiedad WindowStyle, puede controlar cómo los usuarios pueden cambiar el tamaño de la ventana (y si es posible). La elección del estilo de ventana determina si un usuario puede cambiar el tamaño de la ventana arrastrando su borde con el mouse, si los botones para Minimizar, Maximizar y Cambiar el tamaño aparecen en el área distinta del cliente y, si es así, si están habilitados.

Puede configurar cómo cambia el tamaño de una ventana si establece su propiedad ResizeMode, que puede ser uno de los valores siguientes de la enumeración ResizeMode:

Como sucede con WindowStyle, no es probable que el modo de cambio de tamaño de una ventana varíe durante su vigencia, lo que significa que probablemente lo establecerá desde el marcado XAML.

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    ResizeMode="CanResizeWithGrip">
</Window>

Tenga en cuenta que puede inspeccionar la propiedad WindowState para detectar si una ventana está maximizada, minimizada o restaurada.

Estilo de ventana

El borde que se expone desde el área distinta del cliente de una ventana es adecuado para la mayoría de las aplicaciones. Sin embargo, hay circunstancias donde se necesitan tipos diferentes de borde o no se necesita ningún borde en absoluto, dependiendo del tipo de ventana.

Para controlar qué tipo de borde obtiene una ventana, establezca su propiedad WindowStyle con uno de los valores siguientes de la enumeración WindowStyle:

El efecto de estos estilos de ventana se muestra en la ilustración siguiente:

Ilustración de estilos de borde de ventana.

Puede establecer WindowStyle mediante marcación o código XAML. Dado que es improbable que cambie durante la vigencia de una ventana, probablemente lo configurará mediante marcación XAML.

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    WindowStyle="ToolWindow">
</Window>

Estilo de ventana no rectangular

También hay situaciones en las que los estilos de borde que permite WindowStyle no son suficientes. Por ejemplo, es posible que quiera crear una aplicación con un borde no rectangular, similar a la del Reproductor de Windows Media de Microsoft.

Considere, por ejemplo, la ventana de globo que se muestra en la ilustración siguiente:

Bocadillo de diálogo que dice

Este tipo de ventana se puede crear si se establece la propiedad WindowStyle en None y se usa la compatibilidad especial que tiene Window para la transparencia.

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    WindowStyle="None"
    AllowsTransparency="True"
    Background="Transparent">
</Window>

Esta combinación de valores indica a la ventana que se puede representar de forma totalmente transparente. En este estado, no se pueden usar las opciones del área distinta del cliente de la ventana (el menú Cerrar, los botones para minimizar, maximizar y restaurar, etc.). Por consiguiente, deberá proporcionar las suyas propias.

Presencia de la barra de tareas

El aspecto predeterminado de una ventana incluye un botón de barra de tareas, como el que se muestra en la siguiente ilustración:

Captura de pantalla que muestra una ventana con un botón de barra de tareas.

Algunos tipos de ventanas no tienen un botón de barra de tareas, como los cuadros de mensaje o los cuadros de diálogo (consulte Información general sobre cuadros de diálogo). Puede controlar si se muestra el botón de barra de tareas de una ventana estableciendo la propiedad ShowInTaskbar (true de forma predeterminada).

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    ShowInTaskbar="False">
</Window>

Consideraciones sobre la seguridad

Window requiere el permiso de seguridad UnmanagedCode para poder crear una instancia. Para aquellas aplicaciones instaladas e iniciadas desde la máquina local, esto pertenece al conjunto de permisos que se conceden a la aplicación.

Sin embargo, esto no pertenece al conjunto de permisos concedidos a las aplicaciones que se inician desde Internet o desde una zona de intranet local que usa ClickOnce. Por consiguiente, los usuarios recibirán una advertencia de seguridad de ClickOnce y tendrán que elevar el conjunto de permisos de la aplicación para que sean de plena confianza.

Además, XBAP no puede mostrar ventanas ni cuadros de diálogo de forma predeterminada. Para obtener información sobre consideraciones de seguridad de una aplicación independiente, consulte Estrategia de seguridad de WPF: Seguridad de plataforma.

Otros tipos de ventanas

NavigationWindow es una ventana diseñada para hospedar contenido navegable. Para más información, consulte Información general sobre navegación.

Los cuadros de diálogo son ventanas que se suelen utilizar para recopilar información de un usuario para completar una función. Por ejemplo, cuando un usuario desea abrir un archivo, una aplicación muestra normalmente el cuadro de diálogo Abrir archivo para obtener el nombre de archivo del usuario. Para obtener más información, vea Información general sobre cuadros de diálogo.

Consulte también