Ventana sin marco que puede cambiarse de tamaño, moverse, y cerrarse
En este artículo se estudia como definir una ventana WPF para que se muestre sin marco y que cumpla las siguientes propiedades:
Aparentemente, y pensando en visiones anteriores, se podría esperar un código bastante complejo, pero en WPF es mucho mas sencillo que lo que puede parecer,
Esta es la ventana que quiero mostrar y sobre la que trabajamos
Imagen de la ventana que genera este código
<Window x:Class="WindowEsperaSimple" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Title="Window Espera" WindowStyle="None" AllowsTransparency="True" Background="Transparent" ShowInTaskbar="False" MouseDown="Window_MouseDown" MouseRightButtonDown="Window_MouseRightButtonDown" Height="200" Width="320" ResizeMode="CanResizeWithGrip"> <Window.CommandBindings> <!-- Menu Archivo --> <CommandBinding Command="ApplicationCommands.Close" Executed="CloseCommandBinding_Executed" CanExecute="CloseCommandBinding_CanExecute"/> </Window.CommandBindings> <Window.InputBindings> <!-- Menu Archivo --> <KeyBinding Command="ApplicationCommands.Close" Key="F4" Modifiers="Alt" /> </Window.InputBindings> <Border BorderBrush="#FFE9DBF9" BorderThickness="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" CornerRadius="10" Background="#FFE9DBF9" > <Grid Margin="1"> <Grid.RowDefinitions> <RowDefinition Height="auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <StackPanel HorizontalAlignment="Right" VerticalAlignment="Center" Orientation="Horizontal"> <!-- imagen ayuda (negro) arriba a la izquierda --> <Viewbox Width="16" Height="16" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> <Rectangle Width="16" Height="16" > <Rectangle.ToolTip> <StackPanel Orientation="Vertical"> <TextBlock Text ="Mover la ventana : [Botón izquierdo] del ratón: " /> <TextBlock Text ="Cerrar la ventana:" /> <TextBlock Text =" - [Botón derecho] del ratón, O bien," /> <TextBlock Text =" - [Alt + F4]."/> </StackPanel> </Rectangle.ToolTip> <Rectangle.Fill> <DrawingBrush> <DrawingBrush.Drawing> <DrawingGroup> <DrawingGroup.Children> <GeometryDrawing Brush="#00FFFFFF" Geometry="F1M16,16L0,16 0,0 16,0z" /> <GeometryDrawing Brush="#FFF6F6F6" Geometry="F1M0,8C0,3.582 3.582,0 8,0 12.418,0 16,3.582 16,8 16,12.418 12.418,16 8,16 3.582,16 0,12.418 0,8" /> <GeometryDrawing Brush="#FF424242" Geometry="F1M11,7C11,8.104,10.102,9,9,9L9,10 7,10 7,9C7,7.896,7.897,7,9,7L9,5.203C8.841,5.115 8.495,5 8,5 7.505,5 7.159,5.115 7,5.203L7,6 5,6 5,5C5,3.841 6.262,3 8,3 9.738,3 11,3.841 11,5z M9,13L7,13 7,11 9,11z M8,1C4.134,1 1,4.134 1,8 1,11.865 4.134,15 8,15 11.866,15 15,11.865 15,8 15,4.134 11.866,1 8,1" /> <GeometryDrawing Brush="#FFF0EFF1" Geometry="F1M9,11L7,11 7,13 9,13z M9,10L7,10 7,9C7,7.896,7.897,7,9,7L9,5.203C8.841,5.115 8.495,5 8,5 7.505,5 7.159,5.115 7,5.203L7,6 5,6 5,5C5,3.841 6.262,3 8,3 9.738,3 11,3.841 11,5L11,7C11,8.104,10.102,9,9,9z" /> </DrawingGroup.Children> </DrawingGroup> </DrawingBrush.Drawing> </DrawingBrush> </Rectangle.Fill> </Rectangle> </Viewbox> <!-- /Eof imagen ayuda (negro) arriba a la izquierda --> </StackPanel> <Label x:Name="labelTitulo" Grid.Row="1" Margin="10" Content="Espera.... Estoy trabajando (mas o menos) " HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" VerticalAlignment="Stretch" VerticalContentAlignment="Center" Background="{DynamicResource {x:Static SystemColors.InfoBrushKey}}" /> </Grid> </Border> </Window>
''' <summary> ''' Ventana simple que muestra el mensaje de espera ''' </summary> Public Class WindowEsperaSimple #Region "Eventos de la ventana" ' se usa para mover la ventana pulsando el botón izquierdo del ratón Private Sub Window_MouseDown(sender As Object, e As MouseButtonEventArgs) Me.DragMove() e.Handled = True End Sub ' se usa para CERRAR la ventana pulsando el botón derecho del ratón Private Sub Window_MouseRightButtonDown(sender As Object, e As MouseButtonEventArgs) Me.Close() e.Handled = True End Sub ' se usa para cerrar la ventana usando el comando, llamándolo con algún botón ' en este caso concerto se activa con el juego de teclas [Alt + F4] Private Sub CloseCommandBinding_Executed(sender As Object, e As ExecutedRoutedEventArgs) Me.Close() e.Handled = True End Sub ' el comando siempre se puede ejecutar Private Sub CloseCommandBinding_CanExecute(sender As Object, e As CanExecuteRoutedEventArgs) e.CanExecute = True e.Handled = True End Sub ' al inicializarse la ventana se marca el semáforo Private Sub WindowEsperaSimple_Initialized(sender As Object, e As EventArgs) Handles Me.Initialized _ZIsClosed = False End Sub ' al cerrarse la ventana se marca el semáforo Private Sub WindowEsperaSimple_Closing(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles Me.Closing _ZIsClosed = True End Sub #End Region #Region "Property necesaria para open / close ventana" ' '-------------------------------- ' ' Apunte táctico ' '-------------------------------- ' ' [ZIsClosed] indica: ' ' [True], la ventana esta cerrada o es nothing ' ' [False], la ventana esta visible ' ' la razón de este semáforo, es que cuando se cierra la ventana [CloseVentanaEspera] ' ' y se iguala la instancia a [Nothing], realmente no esta [Nothing] ' ' hasta dentro de un rato (cosas del recolector de basura),y cuando se abre, ' ' da un error. La forma que se me ha ocurrido de evitarlo es esa, poniendo un semáforo. ' ' Un problema parecido ocurre al cerrar la ventana ' '-------------------------------- ' ' se da valor en los eventos del formulario [Closing] y [Initialized] ''' <summary> ''' Indica si la ventana esta cerrada o no ''' </summary> ''' <returns> ''' [True], la ventana esta cerrada (o es nothing) ''' [False], la ventana esta visible ''' </returns> ''' <remarks> ''' se da valor en los eventos del formulario [Closing] y [Initialized] ''' </remarks> Friend ReadOnly Property ZIsClosed As Boolean = False #End Region #Region "Código [VentanaEspera] para copiar en las clases clientes" ' ''' <summary> ' ''' variable que contiene el objeto ventana ' ''' </summary> ' Private WithEvents campoObjWinEspera As WindowEsperaSimple ' ''' <summary> ' ''' Proceso para abrir la ventana ' ''' solo se abre una ventana ' ''' </summary> ' Public Sub VentanaEsperaAbrir() ' ' si la ventana no esta activa ' If campoObjWinEspera Is Nothing OrElse ' campoObjWinEspera.ZIsClosed = True Then ' ' -------------------------------- ' ' Instanciarla ' campoObjWinEspera = New WindowEsperaSimple With { ' .Owner = Me, ' .WindowStartupLocation = WindowStartupLocation.CenterOwner ' } ' 'Mostrar la ventana ' campoObjWinEspera.Show() ' End If ' End Sub ' ''' <summary> ' ''' Proceso para cerrar la ventana ' ''' </summary> ' Public Sub VentanaEsperaCerrar() ' ' si la ventana no esta cerrada ' If Not (campoObjWinEspera Is Nothing) Then ' ' cerrar la ventana ' campoObjWinEspera.Close() ' End If ' End Sub ' ''' <summary> ' ''' Cierre de la ventana de espera ' ''' </summary> ' Private Sub CloseVentanaEspera() ' If Not (campoObjWinEspera Is Nothing) Then ' If campoObjWinEspera.ZIsClosed = False Then ' ' si cierro un objeto ya cerrado o NULL da error ' campoObjWinEspera.Close() ' End If ' ' '------- ' ' ' NOTA ' ' ' En el evento [VentanaEspera.Closed] Que esta un poco mas abajo :-) ' ' ' se da el valor NULL a la ventana --> campoObjWinEspera = Nothing ' ' End If ' End If ' End Sub ' ''' <summary> ' ''' Evento que se produce cuando se esta cerrando la venta espera ' ''' ' lo que hago es declararla NULL ' ''' </summary> ' Private Sub VentanaEspera_Closed(sender As Object, e As EventArgs) Handles campoObjWinEspera.Closed ' campoObjWinEspera = Nothing ' End Sub #End Region End Class
Para quitar el marco solamente hay que poner en la definición de la ventana las siguientes atributos:
WindowStyle="None" AllowsTransparency="True" Background="Transparent" ShowInTaskbar="False"
Podemos usar varias alternativas,
En el evento debe estar la instruccion [Me.Close]. No me molesto en escribirlo, escribir este código es más fácil que la tabla del uno :-))
Por ejemplo [ATL + F4] para que se cierre la ventana. El código necesario es el siguiente:
<Window.CommandBindings> <!-- Menu Archivo --> <CommandBinding Command="ApplicationCommands.Close" Executed="CloseCommandBinding_Executed" CanExecute="CloseCommandBinding_CanExecute"/> </Window.CommandBindings> <Window.InputBindings> <!-- Menu Archivo --> <KeyBinding Command="ApplicationCommands.Close" Key="F4" Modifiers="Alt" /> </Window.InputBindings>
' se usa para cerrar la ventana usando el comando, llamándolo con algún botón ' en este caso concerto se activa con el juego de teclas [Alt + F4] Private Sub CloseCommandBinding_Executed(sender As Object, e As ExecutedRoutedEventArgs) Me.Close() e.Handled = True End Sub ' el comando siempre se puede ejecutar Private Sub CloseCommandBinding_CanExecute(sender As Object, e As CanExecuteRoutedEventArgs) e.CanExecute = True e.Handled = True End Sub
El código necesario es el siguiente:
MouseRightButtonDown="Window_MouseRightButtonDown"
' se usa para CERRAR la ventana pulsando el botón derecho del ratón Private Sub Window_MouseRightButtonDown(sender As Object, e As MouseButtonEventArgs) Me.Close() e.Handled = True End Sub
Para ello pulsaremos el botón izquierdo del ratón y mientras lo mantengamos pulsado la ventana se moverá, para ello hace falta definir el evento [] y su escuchador (lisener) correspondiente []
MouseDown="Window_MouseDown"
' se usa para mover la ventana pulsando el botón izquierdo del ratón Private Sub Window_MouseDown(sender As Object, e As MouseButtonEventArgs) Me.DragMove() e.Handled = True End Sub
ResizeMode="CanResizeWithGrip">
Ventana con el control Grip, que permite el cambio de tamaño
No hace falta escribir código, porque esta instrucción muestra en la parte inferior derecha de e la venta un control [Grip], con toda la funcionalidad de arrastrar la ventana para cambiar su tamaño.
Y eso es todo ( de momento)
© 1997 - - La Güeb de Joaquín | |||||
Joaquín Medina Serrano
|
|||||
|
Codificación | |
Fecha de creación | 2008-01-28T18:16:07Z |
Última actualización | |
![]() |