1

I'm trying to get a ListView to stretch horizontally to fill its parent (a Grid). I defined the ListView.ItemsPanel to be of type StackPanel, with Horizontal orientation. I searched around and found that the trick to get the ListViewItems to stretch horizontally would be to set the "HorizontalContentAlignment" property to "Stretch" on the ItemContainerStyle, which I did.

Unfortunately, I still can't get my items to stretch horizontally. I thought about manually calculating the width of each ListViewItem based on the ActualWidth of the parent container, but that seems too much effort for something that should be more simple.

MainPage.xaml:

    <Grid Grid.Row="1" Height="40">
        <ListView ItemsSource="{x:Bind ViewModel.Numbers}">
            <ListView.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ListView.ItemsPanel>
            <ListView.ItemTemplate>
                <DataTemplate x:DataType="models:MyClass">
                    <Border BorderBrush="red" BorderThickness="1">
                        <TextBlock Text="{x:Bind Number }" HorizontalAlignment="Center" />
                    </Border>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>

MainViewModel.cs:

public class MainViewModel : ObservableRecipient
{
    public List<MyClass> Numbers
    {
        get; set;
    }
    public MainViewModel()
    {
        Numbers = new List<MyClass>() 
        { 
            new MyClass { Number = 1 }, 
            new MyClass { Number = 2 }, 
            new MyClass { Number = 3 }, 
            new MyClass { Number = 4 }, 
            new MyClass { Number = 5 },
            new MyClass { Number = 6 },
            new MyClass { Number = 7 },
            new MyClass { Number = 8 }
        };
    }
}

MyClass.cs

public class MyClass
{
    public int Number
    {
        get; set;
    }
}

The output is: I need the numbers to occupy available horizontal space
I need the numbers to occupy the horizontal available space

I'm using Win UI with the Windows App SDK 1.2.

Can you help?

(I've changed the code to a minimal reproducible case)

2 Answers2

0

This simple code should stretch each item horizontally.

<Grid>
    <ListView
        x:Name="List"
        Grid.Row="1"
        Grid.Column="1"
        ItemsSource="{x:Bind MonthScale}">
        <ListView.ItemTemplate>
            <!--
                I'm assuming that MonthScale is a collection of Month.  
                Replace it with the actual item type.
            -->
            <DataTemplate x:DataType="local:Month">
                <Border>
                    <TextBlock
                        VerticalAlignment="Center"
                        Text="{x:Bind MonthName}" />
                </Border>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>

Also note that I'm using x:Bind instead of Binding. See here.

Andrew KeepCoding
  • 7,040
  • 2
  • 14
  • 21
  • Hi Andrew. I changed the code to a minimal reproducible case which clarifies my intent. As you can see, I need the list of items to be horizontally oriented, but the problem is that they do not occupy all the horizontal available space.... – Rui Barreiros Mar 02 '23 at 15:24
0

You should use a UniformGrid (with a single row) instead of a StackPanel for the ItemsPanel! UniformGrid will stretch to fill its parent, StackPanel cannot. You also need to set ListViewItem.HorizontalContentAlignment to Stretch using ItemContainerStyle.

This works:

<ListView>
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Rows="1" HorizontalAlignment="Stretch"/>
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>
    <ListView.ItemContainerStyle>
        <Style TargetType="{x:Type ListViewItem}">
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
        </Style>
    </ListView.ItemContainerStyle>
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="models:MyClass">
            <Border BorderBrush="red" BorderThickness="1">
                <TextBlock Text="{x:Bind Number}" HorizontalAlignment="Center" />
            </Border>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

If you need even less space between the TextBlocks you can set Margin/Padding in the ListViewItem Style as well.

Smolakian
  • 414
  • 3
  • 15