Saltar al contenido

¿Cómo hacer que todos los controles cambien de tamaño en consecuencia proporcionalmente cuando la ventana está maximizada?

Solución:

En WPF hay ciertos controles de ‘contenedor’ que cambian automáticamente el tamaño de su contenido y hay algunos que no lo hacen.

Aquí hay algunos que lo hacen no cambiar el tamaño de su contenido (supongo que está utilizando uno o más de estos):

StackPanel
WrapPanel
Canvas
TabControl

Aquí hay algunos que hacer cambiar el tamaño de su contenido:

Grid
UniformGrid
DockPanel

Por tanto, casi siempre es preferible utilizar un Grid en lugar de un StackPanel a menos que hagas no desea que se produzca un cambio de tamaño automático. Tenga en cuenta que todavía es posible Grid para no el tamaño de sus controles internos … todo depende de su Grid.RowDefinition y Grid.ColumnDefinition ajustes:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="100" /> <!--<<< Exact Height... won't resize -->
        <RowDefinition Height="Auto" /> <!--<<< Will resize to the size of contents -->
        <RowDefinition Height="*" /> <!--<<< Will resize taking all remaining space -->
    </Grid.RowDefinitions>
</Grid>

Puede obtener más información sobre el Grid control desde el Grid Página de clase en MSDN. También puede obtener más información sobre estos controles de contenedor en la página Descripción general de controles de contenedor de WPF en MSDN.

Se puede lograr un cambio de tamaño adicional utilizando el FrameworkElement.HorizontalAlignment y FrameworkElement.VerticalAlignment propiedades. El valor predeterminado de estas propiedades es Stretch que estirará los elementos para que se ajusten al tamaño de los controles que los contienen. Sin embargo, cuando se establecen en cualquier otro valor, los elementos no estirarse.

ACTUALIZAR >>>

En respuesta a las preguntas de su comentario:

Utilizar el Grid.RowDefinition y Grid.ColumnDefinition configuraciones para organizar una estructura básica primero … es común agregar Grid controles en las celdas del exterior Grid controles si es necesario. También puede utilizar el Grid.ColumnSpan y Grid.RowSpan propiedades para permitir que los controles abarquen varias columnas y / o filas de un Grid.

Es más común tener al menos una fila / columna con un Height/Width de "*" que llenará todo el espacio restante, pero puede tener dos o más con esta configuración, en cuyo caso el espacio restante se dividirá entre las dos (o más) filas / columnas. ‘Auto’ es una buena configuración para las filas / columnas que no están configuradas en ‘”*”‘, pero realmente depende de cómo desee que sea el diseño.

No hay Auto configuración que puede utilizar en los controles de las celdas, pero esto es igual de bueno, porque queremos que el Grid ajustar el tamaño de los controles para nosotros … por lo tanto, no queremos establecer el Height o Width de estos controles en absoluto.

El punto que hice sobre el FrameworkElement.HorizontalAlignment y FrameworkElement.VerticalAlignment properties fue solo para informarle de su existencia … ya que su valor predeterminado ya es Stretch, por lo general, no es necesario establecerlos explícitamente.

los Margin La propiedad generalmente solo se usa para espaciar sus controles de manera uniforme … si arrastra y suelta controles desde Visual Studio Toolbox, VS establecerá el Margin propiedad para colocar su control exactamente donde lo dejó caer, pero en general, esto es no lo que queremos, ya que interferirá con el tamaño automático de los controles. Si hace esto, simplemente elimine o edite el Margin propiedad a la medida de sus necesidades.

Bueno, es bastante sencillo de hacer.

En el controlador de eventos de cambio de tamaño de la ventana, calcule cuánto ha crecido / encogido la ventana y use esa fracción para ajustar 1) Alto, 2) Ancho, 3) Canvas.Top, 4) Canvas.Left propiedades de todos los controles secundarios dentro del lienzo.

Aquí está el código:

private void window1_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            myCanvas.Width = e.NewSize.Width;
            myCanvas.Height = e.NewSize.Height;

            double xChange = 1, yChange = 1;

            if (e.PreviousSize.Width != 0)
            xChange = (e.NewSize.Width/e.PreviousSize.Width);

            if (e.PreviousSize.Height != 0)
            yChange = (e.NewSize.Height / e.PreviousSize.Height);

            foreach (FrameworkElement fe in myCanvas.Children )
            {   
                /*because I didn't want to resize the grid I'm having inside the canvas in this particular instance. (doing that from xaml) */            
                if (fe is Grid == false)
                {
                    fe.Height = fe.ActualHeight * yChange;
                    fe.Width = fe.ActualWidth * xChange;

                    Canvas.SetTop(fe, Canvas.GetTop(fe) * yChange);
                    Canvas.SetLeft(fe, Canvas.GetLeft(fe) * xChange);

                }
            }
        }

Pensé en compartir esto con cualquiera que necesite más claridad sobre cómo lograrlo:

myCanvas es un control Canvas y padre de todos los demás controladores. Este código funciona para cambiar el tamaño de forma ordenada a cualquier resolución desde 1366 x 768 en adelante. Probado hasta una resolución de 4k 4096 x 2160

Tome nota de todas las configuraciones de propiedades de MainWindow (WindowStartupLocation, SizeToContent y WindowState) – importante para que esto funcione correctamente – Se maximizó el requisito de WindowState para mi caso de usuario

xaml

<Window x:Name="mainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:MyApp" 
    xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
    x:Class="MyApp.MainWindow" 
     Title="MainWindow"  SizeChanged="MainWindow_SizeChanged"
    Width="1366" Height="768" WindowState="Maximized" WindowStartupLocation="CenterOwner" SizeToContent="WidthAndHeight">
  
    <Canvas x:Name="myCanvas" HorizontalAlignment="Left" Height="768" VerticalAlignment="Top" Width="1356">
        <Image x:Name="maxresdefault_1_1__jpg" Source="maxresdefault-1[1].jpg" Stretch="Fill" Opacity="0.6" Height="767" Canvas.Left="-6" Width="1366"/>

        <Separator Margin="0" Background="#FF302D2D" Foreground="#FF111010" Height="0" Canvas.Left="-811" Canvas.Top="148" Width="766"/>
        <Separator Margin="0" Background="#FF302D2D" Foreground="#FF111010" HorizontalAlignment="Right" Width="210" Height="0" Canvas.Left="1653" Canvas.Top="102"/>
        <Image x:Name="imgscroll" Source="BcaKKb47i[1].png" Stretch="Fill" RenderTransformOrigin="0.5,0.5" Height="523" Canvas.Left="-3" Canvas.Top="122" Width="580">
            <Image.RenderTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <SkewTransform/>
                    <RotateTransform Angle="89.093"/>
                    <TranslateTransform/>
                </TransformGroup>
            </Image.RenderTransform>
        </Image>

.cs

 private void MainWindow_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        myCanvas.Width = e.NewSize.Width;
        myCanvas.Height = e.NewSize.Height;

        double xChange = 1, yChange = 1;

        if (e.PreviousSize.Width != 0)
            xChange = (e.NewSize.Width / e.PreviousSize.Width);

        if (e.PreviousSize.Height != 0)
            yChange = (e.NewSize.Height / e.PreviousSize.Height);

        ScaleTransform scale = new ScaleTransform(myCanvas.LayoutTransform.Value.M11 * xChange, myCanvas.LayoutTransform.Value.M22 * yChange);
        myCanvas.LayoutTransform = scale;
        myCanvas.UpdateLayout();
    }
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *