WPF DataGrid - Why the extra column
Asked Answered
H

4

30

I have a WPF app that uses DataGrid to display some data. When I run the program there is an additional column as shown here: enter image description here

Here is what it looks like when I design it in VS2010enter image description here

I have turned off AutoGenerateColumns on the data grid and specified the columns individually as such (this is a user control):

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

I also have a MainWindowView that uses injection to display the views as such (this is a regular window):

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

In the designer I have specified both MainWindowView and EmployeeHoursView as Auto Size root as I want the window to be just large enough to accommodate the grid and button. However, when I run the program I get an additional column in the data grid and it makes the program window about twice as large (both width and height) as the EmployeeHoursView needs to be. How can I code this such that my application window is just large enough for the EmployeeHoursView without providing specific values? What is causing this additional column to appear?

Harber answered 13/12, 2011 at 18:34 Comment(0)
K
45

The "extra column" is actually just unused space. Each of your columns define a Width value, so once they get assigned there is space left over.

If you want to get rid of that space, make at least one of your columns a * column so it stretches to fill available space.

My best guess as to why it looks normal in Visual Studio is probably because you have the designer width set to something smaller than the runtime width. If it were larger, you'd see the same thing.

If you don't want your control to stretch, then be sure to set it's (or it's parent's) horizontal/vertical alignment to something other than Stretch

<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
    <ItemsControl ItemsSource="{Binding ViewModels}" Margin="3" />
</StackPanel>
Kee answered 13/12, 2011 at 18:51 Comment(5)
But isn't that the point of Auto Size, to size the elements (the data grid in this case and the main window by proxy) to just what is needed? Where else would a sizing element be coming into play? If I change the last column's Width to "*" then the overall window size is still the same and now I have a super wide column.Harber
@Harber From Microsoft's MSDN site: Auto sizing behavior implies that the element will fill the width available to it. Note however that specific controls frequently supply default values in their default styles that will disable the auto sizing behavior unless it is specifically re-enabled. msdn.microsoft.com/en-us/library/…Kee
Thanks, that helped point me in the direction of SizeToContent on the MainWindow. Setting this to "WidthAndHeight" now properly sizes the MainWindow based on the size of the datagrid.Harber
Is there a way to display that extra column with some other background color?Canoodle
@VarunMahajan You could try creating an extra blank column for unused space, and setting the RowBackground color of itKee
C
8

Put ColumnWidth="*" in the XAML and it will surely be work.

<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>
Chere answered 10/1, 2019 at 22:25 Comment(0)
L
1

Well since its unused space, another way around will be use a weighted width rather than fixed one. You can use a hybrid approach as well wherein some are fixed and some are weighted, in that case ensure one is weighted (*) So in your code it will be :

<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*" />
Legionary answered 7/3, 2016 at 4:31 Comment(0)
M
1

The area on the left that you are seeing is the Row Headers. Set the HeadersVisibility to either "Column" or "None" (depending on which you want)

Michaeu answered 6/2, 2020 at 21:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.