Xaml Listview Windows-Universal Horizontal Scroll Mode - c#

I coded a list that has as an Itemsource an Observable Collection, which is of type Grids. So the listview is containing 4 Items (Grids). I want the Grids to be like horizontal next to each other, so I tried this in Xaml.
<StackPanel Orientation="Horizontal">
<ListView ScrollViewer.HorizontalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollMode="Enabled" ItemsSource="{Binding DropGrids, Source={StaticResource view}}" Height="100" x:Name="DropList" RenderTransformOrigin="0.5,0.5" >
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
<AppBarButton Icon="MapPin" Label="Go!" HorizontalAlignment="Right"></AppBarButton>
</StackPanel>
But when I try scrolling the list to the left it is instantly going back (If you want to simulate is use WGA resolution 4 Inch Emulator) and I can't see the fourth Grid on the screen. How do I fix this?
The ListView.ItemsPanel property I got from this post:
Stackoverflow Post - Horizontal Mode

Not sure on the Grid part in your ListView itemsource, but I blogged about how to create a Horizontal ListView here
http://depblog.weblogs.us/2015/03/25/show-items-scrolling-horizontally-with-listview-in-winrt/
I hope this helps...
The complete style is set as
<Style x:Name="BaseListViewStyle" TargetType="ListView">
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Enabled" />
<Setter Property="ScrollViewer.VerticalScrollMode" Value="Disabled" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal"
ScrollViewer.HorizontalScrollMode="Enabled"
ScrollViewer.VerticalScrollMode="Disabled"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>

Related

UWP ListView with variable sized items

I'm working on UWP with ListView and I'm struggling to implement some basic features.
I have a horizontal ListView with items which need to have variable width. And the width needs to be dynamical, because I want to expand it or retract it based on it's content. To be precise, each item has a number of rectangles inside a StackPanel, I want to be able to add more rectangles, and I would expect the width of the item to increase exponentially.
Right now, the items seem the have equal and locked size. If I increase the content of an item, the other items have the same increased width.
I'm new to UWP, and I can't figure out how to implement such a feature.
<ListView Name="Grid"
Grid.Row="0"
HorizontalAlignment="Stretch"
BorderThickness="0"
ItemsSource="{x:Bind Items, Mode=TwoWay}"
ItemTemplateSelector="{StaticResource TemplateSelector}"
ScrollViewer.HorizontalScrollMode="Enabled"
ScrollViewer.VerticalScrollMode="Disabled"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
IsItemClickEnabled="True"
CanDragItems = "False"
CanDrag = "False"
CanReorderItems = "False"
AllowDrop = "False"
ItemClick="Grid_ItemClick"
SelectionChanged="Grid_SelectionChanged"
SelectionMode="Single">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid VerticalAlignment="Stretch" HorizontalAlignment="Left"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="HorizontalAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
You'll want to change your ItemsPanel to be an ItemsStackPanel with Orientation set to Horizontal. Here's a quick sample:
XAML
<ListView Height="100"
extensions:ListViewExtensions.AlternateColor="Red"
ItemsSource="{x:Bind Items}"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollMode="Auto"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollMode="Disabled">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Width="{Binding Width}">
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
Code
Items = new ObservableCollection<Item>();
for (int i = 0; i < 20; i++)
{
Items.Add(new Item { Index = i, Width = i * 10 });
}
And you can see that each item has a wider width
That is hardly possible with ListView. Maybe ItemRepeater is control for you. Or you can use StackPanel (with horizontal orientation) inside ScrollViewer.

WPF List box with two separated columns

I have to create custom list box the same as on the picture.
I've created UpDown control for each item in list box. But I need to have two columns in list box if will be many items. If it will be two columns, they must be separated as on the picture and each of the column should have border with round corners.
Code for list box is below:
<Style TargetType="{x:Type ListBox}" x:Key="ListBoxService">
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate DataType="{x:Type model:Service}">
<Border
x:Name="border"
VerticalAlignment="Center"
BorderThickness="0, 0, 0, 2"
BorderBrush="{StaticResource CommonBackgroundColor}">
<view:ServiceUpDown/>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<UniformGrid Columns="2" HorizontalAlignment="Center"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Disabled"/>
</Style>
Thanks for any help.
Not a solution for your exact problem, but maybe this can get you started:
<ListBox
ItemsSource="{Binding Items}"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Margin"
Value="0 0 20 0" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
I have set the ListBox' ItemsPanel to a vertical oriented WrapPanel, so once it filled up one "column" in the ListBox it will just wrap into another column.
I have disabled the vertical scrollbar of the ListBoxsince otherwise it would have infinite vertical space, thus the WrapPanelwould never wrap.
This example will wrap the items into additional columns, once all the vertical space of the ListBox has been used. Depending of the vertical size of your listbox and the amount of items there might also be a third or fourth column, when required. You can use the ItemContainerStyle to separate the columns, though this does not resolve the requirement of the rounded borders.

Strange behavior of ListView with WrapGrid in Windows Phone 8.1 XAML

I have a Windows Phone 8.1 XAML app with a ListView nad WrapGrid as its ItemsPanel to display items in two columns
<ListView x:Name="ListV" ItemClick="ListV_ItemClick" IsItemClickEnabled="True">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid Orientation="Horizontal" ItemWidth="160" ItemHeight="280" MaximumRowsOrColumns="2" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<Grid Background="Red" Margin="12" Width="100" Height="100"></Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
The cache mode of the page is set to NavigationCacheMode.Required.
I scoll in the list, tap an item and navigate to another screen. When I navigate back to the page with the ListView, the ListView remebers the scoll position (NavigationCacheMode.Required) but gets "broken", when I tap on items, they just jump strangely.
Here is a complete simple solution to reproduce the problem: https://dl.dropboxusercontent.com/u/73642/listview.zip.
Here is a video showing the problem: https://dl.dropboxusercontent.com/u/73642/listview.wmv
Anyone else experienced this? Is there a way around this issue?
One workaround I've found is to wrap the ListView in a ScrollViewer. Here's a style for vertical scroll viewer:
<Style x:Key="VerticalScrollViewerStyle" TargetType="ScrollViewer">
<Setter Property="HorizontalScrollBarVisibility" Value="Disabled" />
<Setter Property="VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled" />
<Setter Property="ScrollViewer.VerticalScrollMode" Value="Enabled" />
<Setter Property="ScrollViewer.ZoomMode" Value="Disabled" />
</Style>
And then you wrap the ListView like this:
<ScrollViewer Style="{StaticResource VerticalScrollViewerStyle}">
<ListView ...>
...
</ListView>
</ScrollViewer>
This way the ListView's internal ScrollViewer is not used, and this seems to solve your problem. Now, there might be some issues with some features of the ListView that depend on the internal ScrollViewer to be used (e.g. incremental loading). You'll test it and you'll see if what you need works.

Stretch GridView to parent control bounds

I have a custom control where I place my SemanticZoom with GridView inside.
The problem is that if GridView has only few items to display then width of the SemanticZoom is less than width of the container. As the result zoom in\out button is placed incorrectly in the middle of the screen.
If there are many items to display, then GridView stretches itself up to the parent control bounds and everything is ok.
How to stretch Semantic zoom (or inner GridView) properly even if there are only few items inside?
Custom container code:
<controls:DataLoader Grid.RowSpan="2" >
<controls:DataLoader.DataContent>
<SemanticZoom x:Name="SemanticZoom" Style="{StaticResource SemanticZoomStyle}" Margin="0,0,0,0" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch">
<SemanticZoom.ZoomedOutView>
..skipped..
</SemanticZoom.ZoomedOutView>
<SemanticZoom.ZoomedInView>
<GridView x:Name="ZoomedInView"
ItemsSource="{Binding Source={StaticResource GroupedPatients}}"
ItemTemplate="{StaticResource PatientItemTemplate}"
Style="{StaticResource DataGridViewStyle}"
behaviors:SelectionChangedCommandBehavior.Command="{Binding SelectPatientCommand}" Margin="0,0,0,0"
HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch"
Background="Yellow">
<GridView.GroupStyle>
<GroupStyle HeaderTemplate="{StaticResource PatientItemGroupHeaderTemplate}">
<GroupStyle.Panel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid Orientation="Vertical"/>
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</GridView.GroupStyle>
</GridView>
</SemanticZoom.ZoomedInView>
</SemanticZoom>
</controls:DataLoader.DataContent>
GridView style:
<Style x:Key="DataGridViewStyle" TargetType="GridView">
<Setter Property="IsItemClickEnabled" Value="True"/>
<Setter Property="SelectionMode" Value="None"/>
<Setter Property="VerticalAlignment" Value="Stretch"/>
<Setter Property="Width" Value="Auto"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Margin" Value="0"/>
</Style>
</controls:DataLoader>
The correct solution is to use Grid instead of GridView

Using A WrapPanel in a TreeView

I want to display data with level of detail, so i use a TreeView, but each detail is quite short, so i would like to use a WrapPanel (horizontal) to have many details per line.
Something like :
This is an unexpanded item
This is The Header of an expanded item
Info 1 Info 2 Info 3 Info 4
Info 5 Info 6 Info 7
So i tried defining TreeViewItem's Template but i could not get the wrappanel to
wrap. I have only one info per line, when info's datatemplate width is 100 and TreeView
is 500. i tried setting Width of WrapPanel, ItemsWidth, are other things with no success.
Any idea ?
EDIT : i finally got this to work with a 'simpler' solution. Still it seems that we
have to define the WrapPanel's Width, which make the solution less generic.
Here's the solution i came to : just defining, in a style, the ItemsPanel used in a
TreeViewItem :
<Style TargetType="TreeViewItem">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"
Width="520"
HorizontalAlignment="Stretch"
Margin="0"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
IsItemsHost="True"
/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
And i still let the not working solution here, for completeness sake.
(Why wouldn't it work ???)
<Style TargetType="TreeViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TreeViewItem">
<Grid Margin="2" Width="500">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ContentPresenter Name="PART_Header"
ContentSource="Header"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
!!!! this is the wrapanel not wrapping
<ListBox Name="AllItems" Grid.Row="1" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ItemsPresenter />
</ListBox>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded" Value="False">
<Setter
TargetName="AllItems"
Property="Visibility"
Value="Collapsed" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
EDIT : i finally got this to work with a 'simpler' solution. Still it seems that we
have to define the WrapPanel's Width, which make the solution less generic.
(Maybe a binding of the width (but which ?) would solve this)
Here's the solution i came to : just defining, in a style, the ItemsPanel used in a
TreeViewItem :
<Style TargetType="TreeViewItem">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"
Width="520"
HorizontalAlignment="Stretch"
Margin="0"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
IsItemsHost="True"
/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
You must set
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
to your
<TreeView/>
not for
<WrapPanel/>
example:
<TreeView x:Name="fieldTreeView" Grid.Row="1" Margin="5,0,5,0" Background="Beige"
ItemsSource="{Binding Source={StaticResource bla}}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<TreeView.Resources>
<DataTemplate DataType="{x:Type Model:bla}">
<StackPanel Orientation="Vertical">
<Label Content="{Binding Name}"/>
<TextBox Text=""/>
</StackPanel>
</DataTemplate>
</TreeView.Resources>
<TreeView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</TreeView.ItemsPanel>
</TreeView>
This solution works for me.
Try
Disable the scroll bars
Widen the WrapPanel and see the visual impact, is it effected?
Make a color border/background to track the actual size of the WrapPanel
These will help you trace the problem

Categories

Resources