WPF: Horizontally aligned collection with items of uniform width - wpf

I have a variable number of items bound from view model that need to be displayed horizontally and be selectable.
Each item is represented by a text, these texts vary in length. When I use a list view with a StackPanel with horizontal orientation as its ItemTemplate, the items are only as wide as the text inside.
Is there a way to make them all the same size, meaning the size of the widest one? Ideally without some complex codebehind, using item templates and such?
Note: I can't set some arbitrary minimum width, because I don't know what length the texts can ultimately have (different languages etc)

you can use ListBox which has selection support with UniformGrid as ItemsPanel. UniformGrid will allocate equal space for each element
<ListBox>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Label Content="{Binding}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
example

Related

How do I bind a 1D array to a 2D display (datagrid or gird) in WPF?

I'm trying to set up databinding of a usercontrol. I have an item source List, its length is 64, I want to display it in 8x8 grids instead of 1x64 list because there is not enough room to display in UI. How to do that in WPF?
If they should all be the same size, then I would recommend using a UniformGrid. Here's an example of how you would use a UniformGrid in an ItemsControl:
<ItemsControl ItemsSource="...">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="8" Columns="8" IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
You should be able to substitute ItemsControl for any of its descendants, such as ListBox.
If UniformGrid isn't exactly what you're looking for, my second suggestion would be WrapPanel. That should get you roughly the layout you want, but it wouldn't be a fixed 8x8 grid.
If neither of those panels work for you, I think the only remaining option would be to build your own.

Alternate row color for a wrappanel

I am trying to get an alternate row color effect on a Listbox / wrappanel. However since the orientation is Horizontal, The alternate columns are getting the alternate colors. I want the elements to be listed side ways and then wrapped. How can I set the alternate color on rows based on this.
<ListBox ItemsSource="{Binding MySource}" ItemContainerStyle="{StaticResource alternatingListItemStyle}" AlternationCount="2">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" MaxWidth="300"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding MyCaption}"/>
</DataTemplate>
</ListBox.ItemTemplate>
The possible reason for alternating color for columns is the 'MaxWidth'.
As the MaxWidth for WrapPanel is 300, it's possible to hold more than one item.
If you reduce the maxwidth, it may hold a single item.
Hope this helps.
(Can you explain why you are using a wrap panel in ItemsPanelTemplate?
I am not sure how you want the output to look like.)

Align text vertical and horizontal center in stack panel?

I am trying to align a textblock vertically and horizontally center in a stack panel which is there in Listview but i am only able to get text vetically center but not horizontally. Plus the text is not getting wrapped. Here is the code that i have tried:
<ListBox Name="lstTiles" Margin="12,0,-12,0" Grid.Row="1" SelectionChanged="lstTiles_SelectionChanged">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Background="{StaticResource PhoneAccentBrush}" Width="145" Height="80" Margin="8,8,0,0" Orientation="Vertical" >
<TextBlock Text="{Binding Name}" Tag="{Binding ID}" Style="{StaticResource PhoneTextNormalStyle}" FontSize="15" TextWrapping="Wrap" TextAlignment="Center" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
How can i achieve text vertically, horizontally and textwrap?
It looks like since you have the orientation of the StackPanel set to Horizontal, you're putting textblocks next to each other rather than on top of each other. Since the StackPanel elements take the size of their children, you would be able to visualize this as a horizontal, side-by-side, listing of textblocks. Since each textblock takes the size of the text that is in it, you are going to see blocks that are of varying widths, so centering horizontally is going to have no effect.
You could use margins (a pain) to accomplish equal widths. I don't recommend this.
You could also put grids of a set width in the stack panel, and put the textblocks on the grid. You may be able to set the width of the textblocks to get the right effect, but I can't test this at the moment, and I don't remember if it will cause the text to stretch or not.
For text wrapping, I assume you're talking about within the textblock, and that's easy - just set the textblock's TextWrapping property to Wrap.
Try setting the HorizontalContentAlignment and VerticalContentAlignment properties on the listboxitem. I don't have my dev computer now, so I can't experiment, but here is a post that might help you: Silverlight 3: ListBox DataTemplate HorizontalAlignment. Look at both of the first two answers, and see which one might be most helpful in your situation, substituting center, of course, in place of left, top, or stretch.

Marginal Layout panel like Windows 7 Explorer ListView

In Windows Explorer in Windows 7, items in ListView has flexible margin. So all of icons fit in region of ListView.
How can i make a panel which implemented like this? WrapPanel is most approaching that, it's not flawless - a WrapPanel doesn't fit items to it's boundaries through adjusting margin.
Try using WrapPanel as your ListView's item panel and disable the horizontal scrollbar:
<ListView ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
...
</ListView>
ItemTemplate specifies how each item should be rendered. It has no effect on how items are laid out. ItemsPanel, by contrast, does specify the layout.
Also, you may want all items to be displayed the same size. You can find out how to do that from this article:
http://joshsmithonwpf.wordpress.com/2008/09/06/synchronizing-the-width-of-elements-in-an-itemscontrol/

How can I make a ListBoxItem stretch Vertically

I would like to make a ListBox function like a Grid. Each time a new item is added it should look like a a new GridRow was added (with a height of star). So if there are two items they will each take up half of the available space. At some point the Grid row will be smaller than the items MinHeight at which point the Grid will expand and a containing ScrollViewer can kick in.
You will see this behavior with a grid inside a ScrollViewer. However, I need to get this working with a ListBox so I can just set the ItemsSource, create a DataTemplate and move on.
The problem with the default ListBox ItemsPanel is that it will not let my first item expand to fill all the available space.
UPDATE:
Here's the code to get it working:
<ListBox VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" Width="Auto" Height="Auto">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="1"></UniformGrid>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
This SO post has some pretty good information that seems relevant to your post
WPF - Why Listbox items do not fill uniformgrid

Resources