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>
Related
I have a StackPanel inside a ScrollViewer and I would like to bind items and define their datatemplate so I use a ItemsControl. The problem appears to be the ItemsControl does not implement IScrollSnapPointsInfo and this is breaking my vertical snap points associated with the StackPanel children and the ScrollViewer.
These vertical snap points should allow the items bound to the stack panel to align in the vertical center position of the scroll viewer when the user scrolls.
Bellow is some sample code:
<ScrollViewer x:Name="ScrollViewer"
ZoomMode="Disabled"
ZoomSnapPointsType="None"
VerticalSnapPointsType="Mandatory"
VerticalSnapPointsAlignment="Center">
<ScrollViewer.Content>
<Grid>
<!-- Start StackPanel -->
<StackPanel x:Name="StackPanel" Margin="0,500,0,500" Orientation="Vertical">
<StackPanel.Children>
<ItemsControl ItemsSource="{x:Bind Items, Mode=OneWay}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="model:ScrollItem">
<Button Margin="8,0">
<Button.Content>
<Grid>
<TextBlock Text="Hello" Foreground="Black" FontSize="20" />
</Grid>
</Button.Content>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel.Children>
</StackPanel>
<!-- End StackPanel -->
</Grid>
</ScrollViewer.Content>
</ScrollViewer>
Does anyone have experience with this? any advice on how I can restore the vertical snap points and still bind to the stack panel would be great.
Ideally I would like to just bind a list of items to the stack panel and define the template in xaml. This is much better than creating elements in code etc...
I have a WrapPanel that I'm filling in my ViewModel with UserControls:
<WrapPanel Width="250" Orientation="Horizontal" Margin="3">
<ItemsControl ItemsSource="{Binding PlaceableObjectsContent}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type local:PlaceableObjectViewModel}">
<local:PlaceableObjectUserControl>
<local:PlaceableObjectUserControl.InputBindings>
<MouseBinding MouseAction="LeftClick"
Command="{Binding DataContext.OnPlaceableObjectClicked, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
CommandParameter="{Binding}"/>
</local:PlaceableObjectUserControl.InputBindings>
</local:PlaceableObjectUserControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</WrapPanel>
When I fill them manuell with random Controls, everything works fine! I already read something about problems because of Using ItemTemplate!?
If its true, how can I manage that?
Thanks
You're putting a single ItemsControl inside a WrapPanel. That won't do anything. If you want your ItemsControl to use a WrapPanel to host its own items, here's how:
<ItemsControl
ItemsSource="{Binding PlaceableObjectsContent}"
Width="250"
Margin="3"
>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- etc. -->
Note that something has to constrain the width of the ItemsControl for this to work: Either it must be limited by the size of its parent, or a Grid Column, or even by setting the Width or MaxWidth properties of the ItemsControl element itself, either directly or via a Style.
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.
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.
I do not know what the container/control im looking for would be called, so I cannot really search for it.
Add More of Same Usercontrol Usercontrol
Clicking on + would add a new instance of My Usercontrol to the right of the existing ones
Clicking on X would dispose the usercontrol that was clicked
I'm not really looking for a tab control that would put each new instance on a new tab, but if there is nothing else then it might do.
The design is not to be as shown in the image obviously, the image just illustrates the basic idea
Any keyword/name suggestions or links to existing implementations?
e.g. Maybe there is a style that turns a ListBox into something suitable?
I would use an ItemsControl and customize it's ItemsPanelTemplate to be whatever you want.
ItemsControls are meant for iterating through a collection of objects, and displaying them in whatever form you want. I wrote some simple code samples of them here if you're interested, or here's another quick example:
<DockPanel x:Name="RootPanel">
<Button Style="{StaticResource AddButtonStyle}"
DockPanel.Dock="Right" VerticalAlignment="Center"
Command="{Binding AddItemCommand" />
<ScrollViewer>
<ItemsControl ItemsSource="{Binding MyCollection}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<local:MyUserControl />
<Button Style="{StaticResource RemoveButtonStyle}"
Command="{Binding ElementName=RootPanel, Path=DataContext.RemoveItemCommand}"
CommandParameter="{Binding }"
HorizontalAlignment="Left" VerticalAlignment="Top" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</DockPanel>
Your ItemsControl would be bound to an ObservableCollection of objects, and your Add/Remove buttons would simply add/remove items from that collection. Since it is an ObservableCollection, it will notify the UI when the collection gets changed and automatically update.
You can indeed use a ListBox and set its ItemTemplate and ItemsPanelTemplate:
<ListBox>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Label Content="{Binding Name}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Of course, your ItemTemplate would be a reference to your control.
You could look at something called a carousel control which uses a list of objects behind it and displays them similarly to itunes. This could be a bit over the top but is one solution. An example can be seen here
If this is too advanced for your needs, could it be as simple as a stackpanel with a scrollbar which is bound to a list of your user controls?