Question

I am new to WPF/Xaml and searched for this issue I am facing but found it tough. Requesting some help on this.

I need to display usercontrols (DATABOUND) (horizontally) inside a panel/listview so that they wrap when the width of listview/panel is met, with a vertical scroll bar autoshown (as in figure). enter image description here so far I have this code.

 <ListView Grid.Row="3"
                  ItemsSource="{Binding Controls}"                   
                  VerticalAlignment="Bottom" Background="{x:Null}" BorderBrush="{x:Null}"

                  >



                <ListView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <StackPanel Orientation="Horizontal" Margin="0,0,0,10"></StackPanel>
                    </ItemsPanelTemplate>
                </ListView.ItemsPanel>
                <ListView.ItemContainerStyle>
                    <Style TargetType="ListViewItem">
                        <Setter Property="VerticalContentAlignment" Value="Bottom"/>
                        <Setter Property="Focusable"  Value="False" />
                    </Style>
                </ListView.ItemContainerStyle>
                <!--<ListView.ItemTemplate>
                    <DataTemplate>
                        <ContentControl Content="{Binding}" VerticalContentAlignment="Bottom"/>
                    </DataTemplate>
                </ListView.ItemTemplate>-->
            </ListView>

I have even tried the below code. Yes, it wraps but no scrollbar appears!

    <ItemsControl Grid.Row="3"
              Width="100" Height="200" 
              ItemsSource="{Binding Controls}"                   
              VerticalAlignment="Bottom" Background="{x:Null}" BorderBrush="{x:Null}"

              >

            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>                         
                    <WrapPanel Orientation="Horizontal" Margin="0,0,0,10"></WrapPanel>            
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>


        </ItemsControl>

Note: I am okay with any control that makes this happens. Not necessarily be a listview.

Was it helpful?

Solution

To wrap items you need to set ItemsPanel to WrapPanel, like in second example, but you may need to disable horizontal scrolling on ListView:

<ListView ScrollViewer.HorizontalScrollBarVisibility="Disabled" .../>

also, if you want to use ItemsControl then ScrollViewer is not part of default Template, like for ListView, so you'll need to wrap in in ScrollViewer

<ScrollViewer Grid.Row="3">
   <ItemsControl ...>
      <!-- .... -->
   </ItemsControl>
</ScrollViewer>

and don't forget to move Grid.Row="3" from ItemsControl definition to ScrollViewer

OTHER TIPS

You were close :-)

Put your listview with a view panel that is a wrapanel inside your scrollviewer.

<ScrollViewer>
  <ItemsSource="{Binding Controls}">
    <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
         <WrapPanel></WrapPanel>
      </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel> 
  </ItemsControl>
</ScrollViewer>

You are using Wrap panel so you need to specify the width it supposed to take... since wrappanel is inside a items host control wrap panel itself cannot calculate the width.It will try to take all the width with respective to Orientation (in your case its horizontal)

Here is the sample code with list box as items host... in this code i have binded the wrappanel width to the actual width of the list box so that it will never take more width than the list box and also i disabled the horizontal scrolling which you don't need for horizontal orientation and vertical wrapping

Note: Make sure to change item template before using following code and it will work with all items hosts like ListView, ItemsControl...

<ListBox Width="500" Height="500" Name="listbox" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel Orientation="Horizontal" Width="{Binding ActualWidth,ElementName=listbox}"></WrapPanel>
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid Height="100" Width="100">
                        <TextBlock Text="{Binding}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

For ItemsControl

<ItemsControl Grid.Row="3"
              Width="100" Height="200" 
              ItemsSource="{Binding Controls}"                   
              VerticalAlignment="Bottom" Background="{x:Null}" BorderBrush="{x:Null}"
 Name="listbox"
              >

            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>

                    <WrapPanel IsItemsHost="True" Orientation="Horizontal" Width="{Binding ActualWidth,ElementName=listbox}"></WrapPanel>

                </ItemsPanelTemplate>

            </ItemsControl.ItemsPanel>

            <ItemsControl.Template>
                <ControlTemplate>
                    <ScrollViewer x:Name="ScrollViewer" Padding="{TemplateBinding Padding}">
                        <ItemsPresenter />
                    </ScrollViewer>
                </ControlTemplate>
            </ItemsControl.Template>

            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Grid Height="30" Width="30">
                        <TextBlock Text="{Binding}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
                    </Grid>
                </DataTemplate>
            </ItemsControl.ItemTemplate>

        </ItemsControl>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top