What XAML control should I use to keep all child elements within its borders in WPF?

StackOverflow https://stackoverflow.com/questions/9735878

  •  24-05-2021
  •  | 
  •  

Pergunta

I'm having a UI design issue, this is what I want the contents of my app window to shrink to fit the smallest dimension of the window.

Using the XAML below, when the window is too narrow the contents are shrunk to fit. Perfect. My problem is when the window is too short, the contents fall out the bottom, like this:

<ItemsControl ItemsSource="{Binding GroupStatsDisplayList}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Background="Red" Margin="5" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Viewbox Margin="4" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"  Width="Auto" Height="Auto" >
                <ListBox>
                    <StackPanel Orientation="Horizontal" Margin="5" Background="Blue">
                        <Label Content="{Binding GroupID}" FontWeight="Bold"/>
                        <Label Content="{Binding GroupName}" Width="100" FontWeight="Bold" />
                        <Label Content="{Binding CallsInQueue}" FontWeight="Bold" />
                        <Label Content="{Binding TSF}" FontWeight="Bold" />
                    </StackPanel>
                </ListBox>

            </Viewbox>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

I have read in answers to similar questions that the ItemsControl uses a StackPanel as its default itemspanel and that the StackPanel does behave the way I'm seeing. A grid has been recommended to overcome issues like mine.

So I tried telling my ItemsControl to use a Grid:

<ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid Background="Red" Margin="5" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

Better because the contents do resize when constrained in either direction. Worse because it seems like there is only one ViewBox->ListBox element that gets updated with the last item in my collection (I can see the three items in the collection cycle through the display as the app starts up). I don't see all items in my collection on screen, only the last one.

I also read that a DockPanel could save me...

<ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <DockPanel Background="Red" Margin="5" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

That's when things got crazy and I decided to write this question. Now all items in my collection are there, but they appear one by one when I expand the window horizontally, each new item appears as the existing ones expand to the vertical extent of the window.

How do I get a layout that looks like the first image but will shrink to fit within the smallest dimension of the window?

Foi útil?

Solução

Why do you have a ListBox in your DataTemplate, when you have only one hardcoded item the StackPanel? To clarify that: The ItemTemplate defines how you want one item to appear in your items Collection. For Example you could create an ItemTemplate which shows an Album Cover on the left, the Artist Name next to it and on the bottom a Star Rating. A Grid should not be used as an ItemsPanel, because for that you would need to supply a dynamic Grid/Col Definitions collection. Using a ViewBox is my best advice. But not in the ItemTemplate, this would only size one children, a viewbox around the whole itemscontrol.

Outras dicas

This is the XAML that I used based on the answer from dowhilefor.

    <Viewbox Margin="3" >
    <ItemsControl ItemsSource="{Binding GroupStatsDisplayList}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal" Margin="1" Background="LightGreen">
                    <Label Content="{Binding GroupID}" FontWeight="Bold"/>
                    <Label Content="{Binding GroupName}" Width="100" FontWeight="Bold" />
                    <Label Content="{Binding CallsInQueue}" FontWeight="Bold" />
                    <Label Content="{Binding TSF}" FontWeight="Bold" />
                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Viewbox>

I haven't done WPF in a while, and probably it's not considered very good practice, but maybe you could just use a scaletransform on your entire gui ?

I always liked playing around with them.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top