wpf - modales - ventana modal c#
Ventana fuera de la pantalla cuando se maximiza usando la biblioteca de integraciĆ³n de shell de WPF (5)
Estoy usando la Biblioteca de integración de WPF Shell para crear un cromo personalizado de mi aplicación wpf. Todo está bien, pero al maximizar la aplicación, 6 o 7 píxeles están fuera de la pantalla.
Este es el código que estoy usando:
<Style TargetType="{x:Type local:MainWindow}">
<Setter Property="shell:WindowChrome.WindowChrome">
<Setter.Value>
<shell:WindowChrome
ResizeBorderThickness="6"
CaptionHeight="10"
CornerRadius="0"
GlassFrameThickness="1"/>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MainWindow}">
<Grid>
<Border BorderThickness="1" BorderBrush="#389FD1" Background="#389FD1">
<ContentPresenter Margin="0,22,0,0" Content="{TemplateBinding Content}"/>
</Border>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top" >
<TextBlock Text="{Binding NombreUsuario}" Foreground="White" Margin="5,5,20,5" Opacity=".8" />
<Button Style="{StaticResource ImageButton}" Height="20" Width="20" Margin="0" Click="WindowMinimize" shell:WindowChrome.IsHitTestVisibleInChrome="True">
<Image Height="10" Width="10" Source="/Resources/Images/minimize.png" />
</Button>
<Button Style="{StaticResource ImageButton}" Height="20" Width="20" Margin="0" Click="WindowMaximizeRestore" shell:WindowChrome.IsHitTestVisibleInChrome="True" >
<Image Height="10" Width="10" Source="/Resources/Images/maximize.png" />
</Button>
<Button Style="{StaticResource ImageButton}" Height="20" Width="20" Margin="0" Click="WindowClose" shell:WindowChrome.IsHitTestVisibleInChrome="True">
<Image Height="10" Width="10" Source="/Resources/Images/close.png" />
</Button>
</StackPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Desde here , pensé que intentaría configurar WindowChrome.NonClientFrameEdges
.
Con algunos experimentos resulta que puede obtener el efecto deseado configurándolo en NonClientFrameEdges.Bottom
cuando está maximizado, y configurándolo nuevamente en NonClientFrameEdges.None
cuando no está maximizado.
Esto hace que el margen desaparezca en todos los bordes excepto en el inferior, pero crucialmente hace que la superposición debajo de la barra de tareas ya no suceda.
Es importante que WindowChrome esté configurado antes de WindowState, por lo que en mi código subyacente tengo las funciones (MainGrid2 contiene todo el contenido de la ventana que excluye la barra de estado, y StatusGrid contiene la barra de estado):
private void Maximise()
{
StatusGrid.Margin = new Thickness(7, 0, 7, 0);
MainGrid2.Margin = new Thickness(12, 12, 12, 0);
chrome.NonClientFrameEdges = NonClientFrameEdges.Bottom;
WindowChrome.SetWindowChrome(this, chrome);
WindowState = System.Windows.WindowState.Maximized;
}
private void Restore()
{
StatusGrid.Margin = new Thickness(0);
MainGrid2.Margin = new Thickness(5, 5, 5, 0);
chrome.NonClientFrameEdges = NonClientFrameEdges.None;
WindowChrome.SetWindowChrome(this, chrome);
WindowState = System.Windows.WindowState.Normal;
}
En mi proyecto, tengo CaptionHeight establecido en 0 y ResizeMode establecido en CanResizeWithGrip. Este es el código que se me ocurrió para el grosor adecuado.
Thickness maximizeFix = new Thickness(SystemParameters.WindowNonClientFrameThickness.Left +
SystemParameters.WindowResizeBorderThickness.Left,
SystemParameters.WindowNonClientFrameThickness.Top +
SystemParameters.WindowResizeBorderThickness.Top
- SystemParameters.CaptionHeight,
SystemParameters.WindowNonClientFrameThickness.Right +
SystemParameters.WindowResizeBorderThickness.Right,
SystemParameters.WindowNonClientFrameThickness.Bottom +
SystemParameters.WindowResizeBorderThickness.Bottom);
Voy a usar un borde como lo hizo Joe Castro y luego unir el espesor a una propiedad que actualizo cuando cambia el estado de la ventana.
El código parece janky pero aún no he encontrado otra solución.
Para resolver el problema de la ventana que sale de la pantalla simplemente configure:
this.ResizeMode = System.Windows.ResizeMode.NoResize;
Consulte la publicación "Configurar la ventana principal de su proyecto WPF" de JAPF para obtener más información.
Windows recorta los bordes de la ventana cuando se maximiza para oscurecer lo que normalmente serían los bordes de cambio de tamaño. Puede evitar esto colocando un borde proxy entre la ventana y su contenido y luego inflar el grosor cuando se maximiza.
Modifiqué el ejemplo que vino con la lib para hacer esto, el mismo cambio básico podría hacerse en su muestra:
<ControlTemplate TargetType="{x:Type local:SelectableChromeWindow}">
<Border BorderBrush="Green">
<Border.Style>
<Style TargetType="{x:Type Border}">
<Setter Property="BorderThickness" Value="0"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=ThisWindow, Path=WindowState}" Value="Maximized">
<Setter Property="BorderThickness" Value="{Binding Source={x:Static shell:SystemParameters2.Current}, Path=WindowResizeBorderThickness}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<Grid [...]/>
</Border>
</ControlTemplate>
Espero que eso ayude.
Para .net 4.5 y superior, los SystemParameters son un poco diferentes, por ejemplo:
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:MainWindow}}, Path=WindowState}" Value="Maximized">
<Setter Property="BorderThickness" Value="{Binding Source={x:Static SystemParameters.WindowResizeBorderThickness}}"/>
</DataTrigger>
esto funcionó para mí:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:shell="clr-namespace:Microsoft.Windows.Shell;assembly=Microsoft.Windows.Shell"
xmlns:Views="clr-namespace:BorderLessWpf.Views">
<Style TargetType="{x:Type Views:ShellView}" >
<Setter Property="shell:WindowChrome.WindowChrome">
<Setter.Value>
<shell:WindowChrome
ResizeBorderThickness="6"
CaptionHeight="10"
CornerRadius="0"
GlassFrameThickness="1"/>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="WindowState" Value="Maximized">
<Setter Property="BorderThickness" Value="6" />
</Trigger>
</Style.Triggers>
</Style>