I have the following code in a Metro app. The listview binds up to a list of objects. My problem is that the WrapGrid assigns them equal width. But some Titles are longer then others so width should be set width to Auto. But this dont work.. anyone have any idea?
<ListView>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<TextBlock Text="{Binding Title}"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
This works for me:
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid ItemWidth="250" ItemHeight="80" MaximumRowsOrColumns="7" VerticalAlignment="Center" HorizontalAlignment="Center" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
The key point here is MaximumRowsOrColumns property. Have fun :)
I think it's not the WrapGrid, but the ListView itself through the ListViewItem/ItemContainerStyle that makes them same size. I don't think there really is a workaround for that though. You could use your own ItemsControl and custom panel or calculate the desired size of each item and based on that - put the items in something like a VariableSizedWrapGrid, setting RowSpan/ColumnSpan appropriately to match that desired size. Other than that - you can either make all items wide enough to fit everything or simply clip the content and display the full strings in the detailed view once the user clicks an item.
Related
i am trying to make a XAML with wrapping list view, or is it a grid, or table. I am just not sure. Please take a look at the image. How would i go about formatting my "list" that needs to wrap around the view, can someone please give me sample XAML, as i have no idea how to realize how to make this view.
It seems i need to use a ListView inside a Wrappanel of some sort? The data is dynamic, such as i can have any number of key/value pairs as seen here (open, high, lose, close, etc...) so keep in mind the pairs can have any number and they need to wrap around the control/window.
Any idea how to define such a XAML?
Thanks.
I've since figured it out. I'm using an itemcontrol instead of a list and put a wrappanel. Like this.
<ItemsControl ItemsSource="{Binding DataItems}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Width="100" Text="{Binding KeyText}"></TextBlock>
<TextBlock Width="100" Text="{Binding ValueText}"></TextBlock>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
EDIT #2:
Here's a minimal Github Repo I created to reproduce the problem.
I believe this is a bug in the implementation of virtualization of a grouped ListViewBase when some groups are empty
I have a listview whose items panel is set to StackPanel since I need to set the group style panel to a staggered panel which doesn't work well with item stack panel.
The problem now is, out of 27 groups, only 16 groups are shown. I tested it on another list view and I confirmed that the problem is that the stack panel only displays a limited number of children (the strange thing is it's not 16 on my test but 22).
I tried VirtualizingStackPanel but unlike StackPanel, I can't seem to center it inside the list view upon setting its MaxWidth though it displays all its children.
Here's my XAML:
<ListView ItemsSource="{Binding Source={StaticResource NoteViewSource}}"
Padding="0 0"
ItemTemplate="{StaticResource NormalNoteTemplate}"
x:Name="ListView"
IsItemClickEnabled="True"
ItemClick="ListView_OnItemClick"
SelectionChanged="ListView_OnSelectionChanged"
SelectionMode="Extended">
<ListView.Footer>
<Border Height="80" />
</ListView.Footer>
<ListView.GroupStyle>
<GroupStyle HidesIfEmpty="False">
<GroupStyle.HeaderTemplate>
<DataTemplate x:DataType="viewModels:NoteList">
<TextBlock Text="{x:Bind Header, Mode=OneWay}"
FontSize="18"
Margin="0,16,0,8"
FontWeight="Bold" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.Panel>
<ItemsPanelTemplate>
<uwp:SGStaggeredPanel DesiredColumnWidth="220"/>
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</ListView.GroupStyle>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<!-- custom group panel won't work if this is item panel-->
<StackPanel />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
Edit:
I inspected it further and it seems that the StackPanel is not the problem since its Children count is 22. This means it has the wrong count of children which means the problem is in the CollectionViewSource or the ListView passing only 22 items in the StackPanel rather than the full count.
But what I can't understand is why does the VirtualizingStackPanel work??
Instead of using the StackPanel, consider using the ItemsStackPanel. It's designed to work with groups.
<ItemsPanelTemplate>
<ItemsStackPanel />
</ItemsPanelTemplate>
From Microsoft docs:
ItemsStackPanel: Arranges child elements of an ItemsControl into a single line that can be oriented horizontally or vertically. Supports pixel-based UI virtualization and grouped layouts.*
SOF Tribe,
I have a request for the identity of a flow container into which I can pour an indeterminate number of dynamically created XAML buttons. Said buttons should wrap the text as closely as possible (I think I have a template for this). But the buttons should wrap like a gridview, but run like a stackpanel. Does anyone know a container that will allow me to accomplish what the image portrays?
Currently, for the existing image below, I'm using a gridview, but the gridview sets a specific width but does flow unevenly. A stackpanel has the desired end-to-butt style but won't wrap. So, any ideas?
There is what is called the UniversalWrapPanel made by Greg Stoll. So, that's the direction I'll be taking. Now however, I've got the last little bit to tackle. How to get the bound data to respect the parent container's ability to wrap content and not just stack it up in a vertical column.
The below XAML gives me the below image result which is not quite what I want. Statically added buttons work just fine to the UniversalWrapPanel. But trying to get a binding and ItemsSource to work, well, that's beyond me at this time.
<support:UniversalWrapPanel Orientation="Horizontal" Background="White">
<ItemsControl x:Name="GridViewRecipients" ItemsSource="{Binding}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Style="{StaticResource ButtonLozengeStyle}" Content="{Binding FullName}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</support:UniversalWrapPanel>
OK, so a bit more searching and I found this:
http://www.visuallylocated.com/post/2015/02/20/Creating-a-WrapPanel-for-your-Windows-Runtime-apps.aspx
and so here is the correct way to reference the UniversalWrapPanel within the ItemsControl:
<ItemsControl x:Name="GridViewRecipients" ItemsSource="{Binding}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<support:UniversalWrapPanel Orientation="Horizontal" Background="DodgerBlue"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Style="{StaticResource ButtonLozengeStyle}" Content="{Binding FullName}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
For the result of:
I am looking for a custom ListView control which arranges the items horizontally and if the max width is reached, add the item to the next row.
The WrapGrid as ListView.ItemsPanel doesn't work because it uses equal width for each item (grid structure).
The WrapPanel from the WinRT XAML Toolkit has no ItemTemplate and I cannot use binding due to missing ItemSource property.
Could I write my own ListView implementation with wrapping? Which methods do I need to override?
The solution is to use the WrapPanel from WinRT XAML Toolkit inside the ListViews ItemsPanel:
<ListView x:Name="Keywords" SelectionMode="Multiple" ItemContainerStyle="{ThemeResource ListViewItemStyle}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding}" Style="{ThemeResource ListViewItemSubheaderTextBlockStyle}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
I am having some issues in my Windows 8.1 app regarding getting a nested ListView to scroll properly. Basically I have the following scenario:
I have a page that needs to display a list of 'packages' in a vertical ListView. Each of those packages then has 1-15 images inside of it that I would then like to display in a horizontal ListView. Basically this means I have a list of lists that I would like to display (display the main list vertically, and for each list in the vertical list, list the images horizontally).
I have this almost working, but when it comes to trying to scroll through the nested ListView of images, it is very difficult because the scroll bar/area is right below the images and most of the time you end up touching the image and "selecting" it instead. I'd like to be able to swipe to scroll but I can't seem to get that to work either.
Is there a better way to approach getting a nested horizontal listview to scroll properly? I think one of the issue may be that my touch events aren't being routed the way I want them to be.
At this point my XAML for this looks like the following:
<ScrollViewer x:Name="OuterScrollView">
<ListView x:Name="ImageRoot" Height="851" Width="656" DataContext="{StaticResource GlobalDataContext}" ItemsSource="{Binding MainImageInfo.ImagePackages}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBox Text="{Binding PackageName}"/>
<ScrollViewer>
<ListView>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding ImageBitmap}" Height="200" Width="200"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ScrollViewer>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ScrollViewer>
Any feedback is appreciated.