Search code examples
c#.netwpflayout

How to resize a certain control based on Window size in WPF?


I have a ListView control where I want to resize the last column in sync with the size of the Window. So if the Window's width increases by 100 units, I want the columns' width to also increase by 100.

Should I be using the Resize event on the Window and use a magic number to resize the column header manually, sort of like?:

columnHeader.Width = windowSize.X - 400;

Solution

  • I can't take full credit for this answer, because I got it here

    But basically this is the idea:

    Replace the "View" in the listView with a GridView. Then, you can specify whatever width you want for the first columns. In this case 100, 50, 50. Then we add a binding on the final column, that takes as input the parent ListView control. But we are allowing a converter to do the dirty work for us.

    <ListView>
        <ListView.View>
          <GridView>
            <GridViewColumn Header="Title" DisplayMemberBinding="{Binding}" Width="100"/>
            <GridViewColumn Header="Title" DisplayMemberBinding="{Binding}" Width="50"/>
            <GridViewColumn Header="Title" DisplayMemberBinding="{Binding}" Width="50"/>
            <GridViewColumn Header="4" DisplayMemberBinding="{Binding}">
            <GridViewColumn.Width>
              <MultiBinding Converter="{StaticResource starWidthConverter}">
                <Binding Path="ActualWidth"  RelativeSource="{RelativeSource AncestorType=ListView}"/>
                <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ListView}"/>
              </MultiBinding>
            </GridViewColumn.Width>
          </GridViewColumn>
         </GridView>
        </ListView.View>
        <ListViewItem>item1</ListViewItem>
        <ListViewItem>item2</ListViewItem>
        <ListViewItem>item3</ListViewItem>
        <ListViewItem>item4</ListViewItem>
      </ListView>
    

    So, in the converter 'Convert' function we do this:

    ListView listview = value[1] as ListView;
    double width = listview.ActualWidth;
    GridView gv = listview.View as GridView;
    for(int i = 0;i < gv.Columns.Count-1;i++)
    {
      if(!Double.IsNaN(gv.Columns[i].Width))
        width -= gv.Columns[i].Width;
    }
    return width - 5;// this is to take care of margin/padding
    

    Which grabs the listview width, and calculates the new size.