web-dev-qa-db-fra.com

WPF DataGrid - Pourquoi la colonne supplémentaire

J'ai une application WPF qui utilise DataGrid pour afficher des données. Lorsque je lance le programme, il y a une colonne supplémentaire comme celle-ci: enter image description here

Voici à quoi ça ressemble quand je le conçois dans VS2010enter image description here

J'ai désactivé AutoGenerateColumns sur la grille de données et spécifié les colonnes individuellement en tant que telles (il s'agit d'un contrôle 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 telles (c'est une fenêtre normale):

<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 concepteur, j'ai spécifié MainWindowView et EmployeeHoursView en tant que racine de la taille automatique, car je souhaite que la fenêtre soit suffisamment grande pour accueillir la grille et le bouton. Toutefois, lorsque j'exécute le programme, une colonne supplémentaire apparaît dans la grille de données. La fenêtre du programme est environ deux fois plus grande (largeur et hauteur) que le paramètre EmployeeHoursView doit être. Comment puis-je coder cela de telle sorte que la fenêtre de mon 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?

24
BrianKE

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

Si vous souhaitez vous débarrasser de cet espace, définissez au moins une de vos colonnes sur une colonne * afin qu'elle s'étende de manière à occuper l'espace disponible.

Ma meilleure hypothèse quant à la raison pour laquelle cela semble normal dans Visual Studio est probablement due au fait 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 contrôle s'étire, assurez-vous de définir son alignement horizontal/vertical (ou celui de son parent) sur autre chose que Stretch. 

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

Eh bien, depuis son espace inutilisé, une autre solution consiste à utiliser une largeur pondérée plutôt que fixe. Vous pouvez également utiliser une approche hybride dans laquelle certaines sont fixes et d'autres pondérées. Dans ce cas, assurez-vous que l'une d'entre elles est pondérée (*) Ainsi, 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*" />
1

Mettez ColumnWidth = "*" dans le XAML et ce sera sûrement du travail.

<DataGrid x:Name="DG_FileShow" ColumnWidth="*" ItemsSource="{Binding}" 
 HorizontalAlignment="Left" VerticalAlignment="Top" Height="345" Width="654" 
 Margin="34,53,0,0" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Header="Names" Binding="{Binding}" />
        </DataGrid.Columns>
 </DataGrid>
0
Adeel Kamran