Listbox using UniformGrid - Items not centered - wpf

I have a listbox using UniformGrid for the ItemsPanelTemplate. It is a list of photos. I want the photos to be centered horizontally in the center of each cell of the grid, but it seems that no matter what I do, the images are aligned to the left of each cell. Here is my current XAML:
<Border BorderThickness="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" DockPanel.Dock="Right">
<ListBox Name="PhotosListBox" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid IsItemsHost="True" HorizontalAlignment="Center"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Image Source="{Binding Path=photo}" HorizontalAlignment="Center"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Border>
As you can see, I have the Image control in the DataTemplate set to HorizontalAlignment="Center", which I thought would do it, but it's not working.
What am I doing wrong?

You need to set HorizontalContentAlignment to Stretch to first allow ListBoxItems to stretch to all available space so that inline control can be aligned at centre accordingly.
<ListBox>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>
...
</ListBox>

Related

How to resize ListBoxItems in a horizontal ListBox as the number of items grows [duplicate]

I have a problem with my ListBox in WPF. First of all, I have a horizontal ListBox with custom ItemTemplate. Now, I want to stretch the items, so that the items fits over the complete width of the ListBox. I tried things like setting the HorizontalContentAlignment to Stretch, but this still not working.
Here is my ItemTemplate:
<DataTemplate x:Key="ListViewStepTemplate">
<Grid VerticalAlignment="Stretch">
<TextBlock Text="{Binding Path=Title}"
FontSize="15"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
<Image Height="16"
Width="16"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Source="/images/Content/check_16x16.png"
Visibility="{Binding Path=IsDone, Converter={StaticResource BooleantoVisibilityConverter}, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</DataTemplate>
And this is my ListBox:
<ListBox DockPanel.Dock="Top"
ItemsSource="{Binding AllItemsList}"
SelectedItem="{Binding CurrentItem}"
ItemTemplate="{StaticResource ListViewStepTemplate}"
Height="60"
HorizontalContentAlignment="Stretch">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsEnabled" Value="{Binding IsEnabled, UpdateSourceTrigger=PropertyChanged}" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Padding" Value="30 0" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
If there are 4 items, each item should have a width of 25%. If there are 5 items, each item should have a width of 20% and so on.
Is it possible to do what I want to do? I tried a lot of things now, but it does never work.
Instead of using StackPanel use UniformGrid
Provides a way to arrange content in a grid where all the cells in the grid have the same size.
and bind number of columns to number of items in the list and disable horizontal scrolling functionality.
<ListBox
...
ItemsSource="{Binding AllItemsList}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Disabled" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1" Columns="{Binding AllItemsList.Count}"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<!-- style -->
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Don't use a StackPanel, use an UniformGrid instead.
<ItemsPanelTemplate>
<UniformGrid Rows="1" Columns="{Binding DataContext.Count, RelativeSource={RelativeSource Self}}"/>
</ItemsPanelTemplate>

Scrolling Listbox Fails To Scroll items Horizontally

I have a Listbox where i am binding a list of strings to it. By default the items in the List box scroll vertically. But I want these items to scroll horizontally. Here is the piece of xaml I have.
<ListBox Grid.Row="1" FontSize="25" Name="lstitems" Height="400"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Disabled">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Padding" Value="0,15,0,0"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Name="tbl" Text="{Binding}">
<LineBreak></LineBreak>
</TextBlock>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I tried various approaches but it does not scroll horizontally. With this code I am able to move the items to the left but the rest of the items are not being loaded. The item source property is set from the cs file.
You might try to use a WrapPanel oriented vertically.
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
Also, don't forget to set ScrollViewer.HorizontalScrollBarVisibility to Auto

User Controls Wrapped inside a panel MVVM

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).
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.
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
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>

How as items listbox Horizontal Alignment Center?

A have listbox
<ListBox>
<ListBox.ItemTemplate>
<DataTemplate>
<DockPanel>
<Button Content="{Binding name_trainer}" Tag="{Binding idPersonTrainer}" DockPanel.Dock="Top" HorizontalAlignment="Center">
</Button>
</DockPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox HorizontalContentAlignment="Center">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding yourstuff}" FontSize="72"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel HorizontalAlignment="Center"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
The accepted answer is right, however I needed a bit more:
not only to center, but also to horizontally stretch the items. Just changing HorizontalAlignment to Stretch didn't work, so, here's how it's done:
<ItemsPanelTemplate>
<StackPanel HorizontalAlignment="Stretch">
<StackPanel.Resources>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Center"/>
</Style>
</StackPanel.Resources>
</StackPanel>
</ItemsPanelTemplate>
You may have to center the DockPanel, rather than the data inside it. I've seen this behavior with StackPanel, because the panel shrinks to the contents. The centering ends up working properly, but in the wrong context.

Silverlight: Set Items Widths in ItemsControl to Stretch

I've got an ItemsControl which fills from top to bottom, but I can't get it's child items to occupy the whole width of the ItemsControl:
I basically need to stretch the green bits to fill the width of the control (as shown by the blue bits).
I've tried things like setting the HorizontalAlignment property of the template item to Stretch and I've even tried binding it's Width property to the ItemsControl Width, but neither worked.
Should be a straight forward one, but it's something I just can't quite figure out...
Edit: here's the ItemTemplate (the whole thing is the ItemTemplate which itself contains an ItemsControl which is bound to a list of child objects):
<DataTemplate>
<Border CornerRadius="5" Background="#ddd">
<StackPanel>
<TextBlock Text="{Binding Name}" FontSize="18" Foreground="#bbb"/>
<ItemsControl ItemsSource="{Binding PlugIns}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel HorizontalAlignment="Stretch" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Margin="10,0,10,10" Tag="{Binding}"
MouseEnter="StackPanel_MouseEnter">
<Border Child="{Binding Icon}" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Border>
</DataTemplate>
You need to configure the ListBoxItem HorizontalContentAlignment, you do this by using a Style object in the ListBox ItemContainerStyle as follows:-
<ListBox ....>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListBox.ItemContainerStyle>
OK, so as I continued to build the app up, I figured out how to resolve this. Essentially, when I changed the template of the ItemsControl to support scrolling, the items spanned to fill horizontally :)
<ItemsControl>
<ItemsControl.Template>
<ControlTemplate>
<ScrollViewer Padding="{TemplateBinding Padding}">
<ItemsPresenter />
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
...
</ItemsControl>

Resources