apc
apc

Reputation: 5566

WPF DataGrid - Last Column MinWidth = Auto, Width = *

In WPF how can I have the last column fill the remaining space BUT have a minimum width based on the content (Auto).

Therefore if the content is short it will stretch to fill the remaining space but if the content is long it will scroll rather than cropping the text.

Unfortunately the MinWidth property on the column is a Double and cannot be set to Auto.

Top grid shows column with short text and Width="Auto". Bottom grid shows long text with Width="*".

Ideally in the top example the 2nd col would extend to the end and in the bottom example we would get scrolling.

enter image description here

XAML:

 <StackPanel>
        <DataGrid Name="DataGrid1" Margin="5" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Width="100" Binding="{Binding Col1}"></DataGridTextColumn>
                <DataGridTextColumn Width="Auto" Binding="{Binding Col2}"></DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>
        <DataGrid Name="DataGrid2" Margin="5"  AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Width="100" Binding="{Binding Col1}"></DataGridTextColumn>
                <DataGridTextColumn Width="1*" Binding="{Binding Col2}"></DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>
    </StackPanel>

Code Behind:

 Public Class ExampleObject
    Public Property Col1 As String
    Public Property Col2 As String
End Class

Public Sub New()

    ' This call is required by the designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.


    Dim items1 As New List(Of ExampleObject)
    items1.Add(New ExampleObject With {.Col1 = "Hello", .Col2 = "World"})
    DataGrid1.ItemsSource = items1

    Dim items2 As New List(Of ExampleObject)
    items2.Add(New ExampleObject With {.Col1 = "Hello", .Col2 = "World, Please provide a code sample when asking a question: stackoverflow.com/help/mcve"})
    DataGrid2.ItemsSource = items2
End Sub

Upvotes: 0

Views: 2114

Answers (2)

apc
apc

Reputation: 5566

While not technically making the last column fill the space but with a minimum width of Auto the following gives the same appearance to the user by adding a dummy column which fills the space but styled to appear as part of the last real column.

Couple of points to note:

  • If handling events based on a cell or if the grid is not read only there you may need to take into account the user may select the filler column
  • I have not styled the header in this example.

     <DataGrid Name="DataGrid1" Margin="5" IsReadOnly="True" AutoGenerateColumns="False" GridLinesVisibility="None">
        <DataGrid.CellStyle>
            <Style TargetType="DataGridCell">
                <Setter Property="BorderBrush" Value="Black"></Setter>
                <Setter Property="BorderThickness" Value="0,0,1,1"></Setter>
            </Style>
        </DataGrid.CellStyle>
        <DataGrid.Columns>
            <DataGridTextColumn Width="100" Binding="{Binding Col1}"/>
            <DataGridTextColumn Width="Auto" Binding="{Binding Col2}">
                <DataGridTextColumn.CellStyle>
                    <Style TargetType="DataGridCell">
                        <Setter Property="BorderBrush" Value="Black"></Setter>
                        <Setter Property="BorderThickness" Value="0,0,0,1"></Setter>
                    </Style>
                </DataGridTextColumn.CellStyle>
            </DataGridTextColumn>
            <DataGridTextColumn Width="1*" x:Name="FillerColumn"/>
    
        </DataGrid.Columns>
    </DataGrid>
    

Upvotes: 0

Kacper Stachowski
Kacper Stachowski

Reputation: 975

You can't do that in default DataGrid. Min and max size (either width or height) has to be set to a number value. Setting column size to Auto or to * value defines how it will behave in the DataGrid and you have to choose which kind of behavior you want to use. You can't have both at the same time. It's kinda like saying that you want your control to be red and blue at the same time.

You probably could achieve your goal somehow, but I think it would require rewriting DataGrid to a custom implementation.

Upvotes: 0

Related Questions