I have a ListBox that contains items derived from UserControl. The concrete UserControl contains (among others) a DataGrid. Basically I cannot change the concrete UserControl (changes only for testing purpose; its kind of third party). The DataGrid column width of all columns gets broken as soon as one column width is set to "*", which is required to fill the complete space.
I can reproduce it with a simplified example (w/o UserControl). So if I add a DataGrid as ListBoxItem, specifying a column width of "*" breaks the column width. BTW, the columns also cannot be resized by the user anymore.
Simple example:
<Window x:Class="DataGridSpike.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ListBox HorizontalContentAlignment="Stretch" >
<!-- Column width is basically ok but only since not "*" -->
<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn Header="Column1"/>
<DataGridTextColumn Header="Column2"/>
<DataGridTextColumn Header="Column3"/>
</DataGrid.Columns>
</DataGrid>
<!-- Broken column width: -->
<DataGrid>
<DataGrid.Columns>
<DataGridTextColumn Header="Column1"/>
<DataGridTextColumn Header="Column2" Width="*"/>
<DataGridTextColumn Header="Column3"/>
</DataGrid.Columns>
</DataGrid>
</ListBox>
</Grid>
Does anyone know how to fix this?
Regards
Based in the suggestion of sa_ddam213 I found a kludge that works.
I have no other idea so far.
I wrapped the DataGrid by a ListView, removed all "decoration" from the ListView, and bound the width of the GridViewColumn to the ActualWidth of the ListView. Maybe some control other than ListView works, too. I was just playing around with ListView. A simple border doesn't work.
The margins have to be tweaked some way and there is a gap on the right side I don't get rid of (but I can live with it). Unless I disable HorizontalScrollBarVisibility of the DataGrid I get strange flashing ghost horizontal scrollbars during dragging the widow width by the mouse.
So here is the XAML that seems to be sufficient.
Note that the actual ListView kludge will be part of the concrete UserControl.
However, the following (simplified) code shows what I did:
<Window x:Class="DataGridSpike.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ListBox HorizontalContentAlignment="Stretch">
<!-- ListView is just a kludge -->
<ListView HorizontalContentAlignment="Stretch" Padding="-4,2,-10,0" BorderThickness="0">
<ListView.View>
<GridView>
<GridView.ColumnHeaderContainerStyle>
<Style>
<Setter Property="FrameworkElement.Visibility" Value="Collapsed"/>
</Style>
</GridView.ColumnHeaderContainerStyle>
<GridViewColumn Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}}" />
</GridView>
</ListView.View>
<DataGrid HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch"
Padding="-2,0" HorizontalScrollBarVisibility="Disabled">
<DataGrid.Columns>
<DataGridTextColumn Header="Column1"/>
<DataGridTextColumn Header="Column2" Width="1*" />
<DataGridTextColumn Header="Column3" />
</DataGrid.Columns>
</DataGrid>
</ListView>
</ListBox>
</Grid>
</Window>
Still, this is only a workaround. Any reasonable "fix" still welcome.
You could bind the DataGrid
width back to the ListBox
ActualWidth
, this will give the DataGrid
an actual size other than Auto
and the *
sizing should work.
<!-- Broken column width: -->
<DataGrid Width="{Binding ActualWidth, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsPresenter}}}" Margin="-2,0,0,0">
<DataGrid.Columns>
<DataGridTextColumn Header="Column1"/>
<DataGridTextColumn Header="Column2" Width="*"/>
<DataGridTextColumn Header="Column3"/>
</DataGrid.Columns>
</DataGrid>
However due to the fact the is some spacing between the content and the edges of the ListBox
, you may have to tweak the Margin
(like I did above) a tiny bit to avoid the DataGrid
going over to the right.
Result:
Width="Auto" will solve the problem. Also you can specify 'MaxWidth' to limit the columnwidth expansion.
<DataGrid.Columns>
<DataGridTextColumn Header="Column1"/>
<DataGridTextColumn Header="Column2" Width="Auto" MaxWidth="200" />
<DataGridTextColumn Header="Column3"/>
</DataGrid.Columns>
Hopes this will help.