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