web-dev-qa-db-fra.com

Quelle est la différence entre la largeur et la largeur réelle dans WPF?

Je travaille actuellement avec Panels dans WPF, et j'ai remarqué qu'en ce qui concerne les propriétés Width et Height, il existe également deux autres propriétés appelées ActualWidth et ActualHeight.

ActualWidth

Obtient la largeur rendue de cet élément. Il s'agit d'une propriété de dépendance. (Hérité de FrameworkElement.)

Width

Obtient ou définit la largeur de l'élément. Il s'agit d'une propriété de dépendance. (Hérité de FrameworkElement.)

Référence: MSDN

Quelqu'un peut-il souligner les différences entre les deux et quand utiliser l'un ou l'autre?

46
Andreas Grech

Width/Height est le demandé ou mise en page Taille. Si vous définissez sur Auto, la valeur est double.NaN lorsque vous accédez à la propriété en code derrière.

ActualWidth/ActualHeight est le rendu Taille. Si vous voulez/avez besoin de la taille réelle de l'article, utilisez cet attribut.

69
Muad'Dib

Je trouve ActualWidth le plus utile lorsque je veux lier la largeur ou la hauteur d'un élément à un autre.

Dans cet exemple simple, j'ai deux boutons disposés côte à côte et un commentaire en dessous qui est limité à la largeur du StackPanel contenant les deux boutons.

<StackPanel>

    <StackPanel Margin="0,12,0,0" Orientation="Horizontal" Name="buttonPanel" HorizontalAlignment="Left" >
         <Button Content="Yes - Arm the missile" FontWeight="Bold" HorizontalAlignment="Left"/>
         <Button Content="No - Save the world" HorizontalAlignment="Left" Margin="7,0,0,0"/>
    </StackPanel>

    <TextBlock Text="Please choose whether you want to arm the missile and kill everybody, or save the world by deactivating the missile." 
               Width="{Binding Path=ActualWidth,ElementName=buttonPanel}" Margin="0,5,0,0" HorizontalAlignment="Left" TextWrapping="Wrap"/>

</StackPanel>
9
Simon_Weaver

ActualWidth tient compte du remplissage de la valeur, vous devez donc à tout moment connaître le nombre Actualwidth au lieu de la largeur et éviter le calcul.

edit: supprimé Margin b/c, il ne fait pas partie de ActualWidth.

6
TWood

ActualWidth est défini par le système de rendu et peut être différent en fonction de la largeur des autres éléments et des contraintes de taille globales. Par conséquent, il ne peut pas être modifié. Width est une propriété qui peut être modifiée et doit être utilisée pour augmenter ou diminuer la largeur de l'élément.

De MSDN :

Cette propriété est une valeur calculée basée sur d'autres entrées de largeur et le système de disposition. La valeur est définie par le système de disposition lui-même, sur la base d'une passe de rendu réelle, et peut donc être légèrement en retard par rapport à la valeur définie de propriétés telles que Width qui sont à la base du changement d'entrée.

3
Andy Mikula

Il y a une très bonne raison ne pas utiliser le ActualWidth pour se lier à (évidemment ActualHeight en conséquence). Lorsque vous définissez le Width d'un élément, sur le ActualWidth d'un autre, vous pouvez briser la chaîne de disposition.

Dans le meilleur des cas, votre élément/contrôle doit être analysé une fois le processus de mise en page du parent (la source de liaison) terminé. Cela signifie du temps supplémentaire. S'il se trouve au même niveau de hiérarchie que le parent, le processus de mise en page nécessite (au moins) deux exécutions pour calculer une taille définitive.

Par exemple, j'avais un contrôle dont la propriété size avait été remplacée dans un style qui le définirait sur TemplatedParent(ne pas faire):

<Rectangle DockPanel.Dock="Top" Width="{TemplateBinding ActualWidth}" 
           Height="1" Fill="#000000"/>

Lors du redimensionnement de la fenêtre contenant, le contrôle empêcherait le conteneur de devenir plus petit et freinerait la disposition. Le paramétrer sur Width résoudra le problème (do):

<Rectangle DockPanel.Dock="Top" Width="{TemplateBinding Width}" 
           Height="1" Fill="#000000"/>

Si vous devez utiliser le ActualWidth en général, quelque chose ne va pas avec votre xaml. Mieux vaut corriger cela au lieu de gâcher les tailles finales de la mise en page.

2
Pascal

C'est exactement cela, la largeur de rendu! = Largeur de mise en page. L'un est destiné à être utilisé pour la mise en page, l'autre est destiné au rendu. Comme avec WinForms, il y avait une taille et une propriété ClientSize, elles diffèrent légèrement et vous devez utiliser la taille de rendu Atual/Client et la largeur/hauteur pour la mise en page.

0
John Leidegren

Vous pouvez définir la propriété Width, mais pas la propriété ActualWidth.

La propriété Width est utilisée pour déterminer la façon dont le panneau est rendu, puis le ActualWidth est défini sur la largeur réelle qui a été utilisée. Cela peut ne pas être la même valeur que Width, selon la taille de ses éléments enfants et les constrictions de son élément parent.

ActualWidth n'est pas défini immédiatement lors de la définition de la propriété Width, mais sera mis à jour (une ou plusieurs fois) pendant le rendu.

0
Guffa