web-dev-qa-db-fra.com

Comment redimensionner proportionnellement toutes les commandes lorsque la fenêtre est maximisée?

Lorsque je clique sur le bouton Agrandir, la fenêtre est agrandie mais les contrôles ne sont pas redimensionnés proportionnellement. Quel est le meilleur moyen de redimensionner les contrôles en conséquence? J'utilise MVVM.

Voici mon code.

<Window x:Class="DataTransfer.View.Window1"
        xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
        Icon="/DataTransfer;component/View/Images/ms_msnexplore.gif"

        ResizeMode="CanResizeWithGrip"
        Title="Window1" Height="500" Width="600">
    <!--Style="{DynamicResource OfficeStyle}"-->
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <!--<ResourceDictionary Source="/DataTransfer;component/View/WindowBase.xaml" />-->
                <!--<ResourceDictionary Source="/DataTransfer;component/Themes/WPFThemes/CalendarResource.xaml" />-->
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>

    <Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width ="*" />
    </Grid.ColumnDefinitions>
        <Button Content="Button" HorizontalAlignment="Left" Margin="52,28,0,0" VerticalAlignment="Top" Width="75" Height="22" />
        <DatePicker Name="dp" HorizontalAlignment="Left" Margin="175,25,0,0" VerticalAlignment="Top" Width="123" Text="aaa" GotFocus="DateGotFocused" LostFocus="OnLeaveArchiveDate"/>
        <Calendar HorizontalAlignment="Left" Margin="47,162,0,0" VerticalAlignment="Top"/>
        <TextBox Name="t1" HorizontalAlignment="Left" Height="23" Margin="337,23,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" LostFocus="LeaveField" />
        <RadioButton Content="RadioButton" HorizontalAlignment="Left" Margin="88,92,0,0" VerticalAlignment="Top"/>
        <CheckBox Content="CheckBox" HorizontalAlignment="Left" Margin="252,96,0,0" VerticalAlignment="Top"/>
        <ComboBox Name="combo" IsEditable="False" Text="aaa" IsReadOnly="True"
                  HorizontalAlignment="Left" Margin="337,89,0,0" VerticalAlignment="Top" Width="120" 
                  Focusable="True" GotFocus="ComboBoxGotFocused" >
            <ComboBoxItem>January</ComboBoxItem>
            <ComboBoxItem>February</ComboBoxItem>
        </ComboBox>
        <TextBlock HorizontalAlignment="Left" Height="40" Margin="260,184,0,0" TextWrapping="Wrap" Text="Text_Block" VerticalAlignment="Top" Width="257"/>

    </Grid>
</Window>
37
Shawn

Dans WPF, certains contrôles "conteneur" redimensionnent automatiquement leur contenu et d'autres non.

Voici quelques-uns qui ne ( ne rediment pas leur contenu (j'imagine que vous utilisez un ou plusieurs de ceux-ci):

StackPanel
WrapPanel
Canvas
TabControl

Voici quelques-uns qui font redimensionner leur contenu:

Grid
UniformGrid
DockPanel

Par conséquent, il est presque toujours préférable d'utiliser un Grid au lieu d'un StackPanel sauf si vous ne voulez pas redimensionner automatiquement arriver. Veuillez noter qu'il est toujours possible pour un Grid de de ne pas dimensionner ses contrôles internes ... tout dépend de votre Grid.RowDefinition et Grid.ColumnDefinition paramètres:

<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>

Pour en savoir plus sur le contrôle Grid, consultez la page Grid Class sur MSDN. Vous pouvez également en savoir plus sur ces contrôles de conteneur à partir de la page Vue d'ensemble des contrôles de conteneur WPF sur MSDN.

Un redimensionnement plus poussé peut être réalisé en utilisant FrameworkElement.HorizontalAlignment et FrameworkElement.VerticalAlignment propriétés. La valeur par défaut de ces propriétés est Stretch, ce qui étendra les éléments à la taille de leurs contrôles. Cependant, lorsqu'ils sont définis sur une autre valeur, les éléments ne seront pas étirés .

MISE À JOUR >>>

En réponse aux questions de votre commentaire:

Utilisez le Grid.RowDefinition et Grid.ColumnDefinition paramètres pour organiser une structure de base d'abord ... il est courant d'ajouter des contrôles Grid dans les cellules des contrôles externes Grid si nécessaire. Vous pouvez aussi utiliser le Grid.ColumnSpan et Grid.RowSpan propriétés pour permettre aux contrôles d’étendre plusieurs colonnes et/ou lignes d’un Grid.

Il est très courant d’avoir au moins une ligne/colonne avec un Height/Width sur "*" qui remplira tout l’espace restant, mais vous pouvez en avoir deux ou plus avec ce paramètre, auquel cas l’espace restant sera divisé entre deux (ou plus) lignes/colonnes. "Auto" est un bon paramètre à utiliser pour les lignes/colonnes qui ne sont pas définies sur "" * ", mais cela dépend vraiment de la manière dont vous souhaitez que la disposition soit.

Il n'y a pas de paramètre Auto que vous pouvez utiliser sur les contrôles dans les cellules, mais c'est tout aussi bien, car nous voulons que Grid redimensionne les contrôles pour nous ... par conséquent, ne veut pas définir le Height ou Width de ces contrôles.

La remarque que j'ai faite à propos du FrameworkElement.HorizontalAlignment et FrameworkElement.VerticalAlignment propriétés était juste pour vous informer de leur existence ... comme leur valeur par défaut est déjà Stretch, vous n'avez généralement pas besoin de les définir explicitement.

La propriété Margin est généralement utilisée pour espacer vos contrôles de manière uniforme ... si vous faites glisser et déposez des contrôles de Visual Studio Toolbox, VS définira la propriété Margin pour qu'elle place votre contrôle exactement où vous l'avez laissé tomber, mais généralement, c'est pas ce que nous voulons, car cela gâcherait le dimensionnement automatique des contrôles. Si vous procédez ainsi, supprimez ou éditez simplement la propriété Margin selon vos besoins.

86
Sheridan

Eh bien, c'est assez simple à faire.

Dans le gestionnaire d'événements de redimensionnement de fenêtre, calculez la taille de la fenêtre agrandie/réduite et utilisez cette fraction pour ajuster 1) Hauteur, 2) Largeur, 3) Canvas.Top, 4) Propriétés de Canvas.Left de tous les contrôles enfants du Toile.

Voici le code:

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);

                }
            }
        }
3
Ron16