2011-12-13 4 views
23

J'ai une application WPF qui utilise DataGrid pour afficher des données. Quand je lance le programme il y a une colonne supplémentaire comme indiqué ici: enter image description hereWPF DataGrid - Pourquoi la colonne supplémentaire

Voici à quoi il ressemble quand je dessine dans VS2010 enter image description here

Je désactivé AutoGenerateColumns sur la grille de données et spécifié les colonnes individuellement en tant que telle (ce qui est une commande de l'utilisateur):

<Grid Margin="10,10,10,10"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition /> 
    </Grid.RowDefinitions> 


    <DataGrid x:Name="EmployeeHours" AutoGenerateColumns="False" ItemsSource="{Binding EmployeeHoursLastWeek}" Width="Auto"> 
     <DataGrid.Columns> 
      <DataGridTextColumn Header="PerceptionistID" Binding="{Binding PerceptionistID}" Width="100" /> 
      <DataGridTextColumn Header="Week Of" Binding="{Binding WeekOf, StringFormat={}{0:MM/dd/yyyy}}" Width="75" /> 
      <DataGridTextColumn Header="Regular Hours" Binding="{Binding WorkHours}" Width="100" /> 
      <DataGridTextColumn Header="PTO Hours" Binding="{Binding PTOHours}" Width="100" /> 
      <DataGridTextColumn Header="Holiday Hours" Binding="{Binding HolidayHours}" Width="100" /> 
     </DataGrid.Columns> 
    </DataGrid> 

    <Button x:Name="ImportHoursButton" Content="Import Hours" 
      Command="{Binding ImportHoursCommand}" 
      Height="25" Width="100" Margin="10" 
      VerticalAlignment="Bottom" HorizontalAlignment="Right"     
      Grid.Row="1" /> 
</Grid> 

J'ai aussi un MainWindowView qui utilise l'injection pour afficher les vues en tant que tel (ce qui est une fenêtre régulière):

<Window x:Class="Sidekick.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:vm="clr-namespace:Sidekick.ViewModel" 
     xmlns:vw="clr-namespace:Sidekick.View" 
     Title="Sidekick"> 

    <!-- Typically done in a resources dictionary -->  
    <Window.Resources> 
     <DataTemplate DataType="{x:Type vm:EmployeeHoursViewModel}"> 
      <vw:EmployeeHoursView /> 
     </DataTemplate> 
    </Window.Resources> 

    <StackPanel> 
     <ItemsControl ItemsSource="{Binding ViewModels}" Margin="3" /> 
    </StackPanel> 

</Window> 

Dans le designer, je l'ai spécifié à la fois MainWindowView et EmployeeHoursView en tant que root Taille Auto que je veux la fenêtre être juste assez grand pour accueillir la grille et le bouton. Cependant, lorsque j'exécute le programme, j'obtiens une colonne supplémentaire dans la grille de données et cela rend la fenêtre du programme à peu près deux fois plus grande (à la fois la largeur et la hauteur) que le EmployeeHoursView doit être. Comment puis-je coder ceci de sorte que ma fenêtre d'application soit juste assez grande pour EmployeeHoursView sans fournir de valeurs spécifiques? Qu'est-ce qui provoque l'apparition de cette colonne supplémentaire?

Répondre

38

La "colonne supplémentaire" est en réalité juste l'espace inutilisé. Chacune de vos colonnes définit une valeur de largeur, donc une fois qu'elles sont assignées il reste de l'espace.

Si vous souhaitez vous débarrasser de cet espace, créez au moins l'une de vos colonnes une colonne * afin qu'elle s'étire pour remplir l'espace disponible. Ma meilleure estimation pour savoir pourquoi cela semble normal dans Visual Studio est probablement parce que la largeur du concepteur est définie sur quelque chose de plus petit que la largeur d'exécution. Si c'était plus grand, vous verriez la même chose.

Si vous ne voulez pas que votre commande pour étirer, alors assurez-vous de le régler est (ou il est de parent) alignement horizontal/vertical autre chose que extensible

<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> 
    <ItemsControl ItemsSource="{Binding ViewModels}" Margin="3" /> 
</StackPanel> 
+0

Mais n'est pas que le point de Taille automatique, pour dimensionner les éléments (la grille de données dans ce cas et la fenêtre principale par proxy) à juste ce qui est nécessaire? Où d'autre un élément de dimensionnement entrerait-il en jeu? Si je change la largeur de la dernière colonne en "*" alors la taille globale de la fenêtre est toujours la même et maintenant j'ai une colonne super large. – BrianKE

+0

@BrianKE Du site MSDN de Microsoft: 'Le comportement de dimensionnement automatique implique que l'élément remplisse la largeur disponible. Notez cependant que les contrôles spécifiques fournissent fréquemment des valeurs par défaut dans leurs styles par défaut qui désactiveront le comportement de dimensionnement automatique à moins qu'il ne soit spécifiquement réactivé. »Http://msdn.microsoft.com/fr-fr/library/system.windows.frameworkelement .width.aspx – Rachel

+0

Merci, cela m'a aidé à pointer vers SizeToContent sur MainWindow. La définition de "WidthAndHeight" ajuste maintenant correctement la MainWindow en fonction de la taille de la grille de données. – BrianKE

1

Eh bien, puisque son espace inutilisé, une autre façon autour sera utiliser une largeur pondérée plutôt que fixe. Vous pouvez utiliser une approche hybride et dans lequel certains sont fixes et certains sont pondérés, dans ce cas, assurer un est pondéré (*) Donc, dans votre code, il sera:

<DataGridTextColumn Header="PerceptionistID" Binding="{Binding PerceptionistID}" Width="4*" /> 
     <DataGridTextColumn Header="Week Of" Binding="{Binding WeekOf, StringFormat={}{0:MM/dd/yyyy}}" Width="3*" /> 
     <DataGridTextColumn Header="Regular Hours" Binding="{Binding WorkHours}" Width="4*" /> 
     <DataGridTextColumn Header="PTO Hours" Binding="{Binding PTOHours}" Width="4*" /> 
     <DataGridTextColumn Header="Holiday Hours" Binding="{Binding HolidayHours}" Width="4*" /> 
Questions connexes