XAML (WP8.1) scrollable ListView and fixed Grid bottom of DataTemplate - xaml

<DataTemplate>
<ScrollViewer>
<Grid>
... same rows and controls 20% of screen
</Grid>
<ListView>
</ListView>
</ScrollViewer>
</DataTemplate>
With this template there are
fixed Grid first
scrollable ListView second
How create template with
scrollable ListView at top
fixed Grid at bottom
?
P.S. There are online or compiled demo different xaml layout/templates?

Don't put a ListView inside a ScrollViewer because you will lose virtualization if you are using it, which will degrade performance significantly.
If you want the Grid to always be visible then use the following:
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListView Grid.Row="0"/>
<Grid Grid.Row="1" Height="100"/> <!-- Set any fixed height -->
</Grid>
</DataTemplate>
If you want the Grid to scroll with the list use a Footer:
<DataTemplate>
<ListView>
<ListView.Footer>
<!-- Set any fixed height -->
<Grid Height="100"/>
</ListView.Footer>
</ListView>
</DataTemplate>

Related

UWP - GridView : how to add an "Add" button after the last item?

I use a GridView to display photos and I search an elegant way to allow user to add a new item to a form.
The form contains a lot of fields: it is displayed in a Pivot, where each PivotItem represents a category of the form.
Some categories contain one or more child items: they are displayed through a Master-Detail page.
It's in this page that I need to display a list of photos: as a photo represents a "sub sub item" of the form, I wouldn't manage the add of a new photo through the CommandBar. But I would like to use an "Add" button after the last item of the GridView containing the photos.
At this time I only found a solution that partially work:
Here is the XAML:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Text="Photos" Grid.Row="0"/>
<StackPanel Orientation="Horizontal" Grid.Row="1">
<GridView ItemsSource="{Binding images}">
<GridView.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Gray" BorderThickness="1"
Padding="10"
Height="150" Width="190">
<Image Stretch="UniformToFill"
Source="{Binding bitmap_image}" />
</Border>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
<Border BorderBrush="Gray" BorderThickness="1"
Padding="10"
Height="150" Width="190">
<Button Command="{Binding Path=DataContext.AddPhotoCommand, ElementName=DetailsPage}"
Height="100" Width="100">
<Viewbox>
<SymbolIcon Symbol="Add"/>
</Viewbox>
</Button>
</Border>
</StackPanel>
</Grid>
As I use a StackPanel, the Add button is no longer visible if I display 3 photos...
=> Is there a better way to do this? Or do you see a an alternative? I'm looking for doing this through a DataTemplateSelector, but that would require me to create a "false" object for displaying the add button...
As I use a StackPanel, the Add button is no longer visible if I display 3 photos...
If you don't mind the button is in the next line of your last photo, you can use WinRTXamlToolkit's WrapPanel instead of StackPanel to avoid the pictures goes out of the window and put the button inside the GridView's FooterTemplate:
Xaml:
<Page
x:Class="AddButtonSample.MainPage"
xmlns:controls="using:WinRTXamlToolkit.Controls"
...
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Text="Photos" Grid.Row="0"/>
<controls:WrapPanel Orientation="Horizontal" Grid.Row="1">
<GridView ItemsSource="{Binding images}">
<GridView.FooterTemplate>
<DataTemplate>
<Button Command="{Binding Path=AddPhotoCommand}" Height="100" Width="100">
<Viewbox>
<SymbolIcon Symbol="Add"/>
</Viewbox>
</Button>
</DataTemplate>
</GridView.FooterTemplate>
<GridView.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Gray" BorderThickness="1"
Padding="10"
Height="150" Width="190">
<Image Stretch="UniformToFill"
Source="{Binding bitmap_image}" />
</Border>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</controls:WrapPanel>
</Grid>
Result:
If you really want to put the Button side by side after the last item of GridView. The only Option is DataTemplateSelector.
The best solution might be to use a CommandBar and put the "Add" button in the very bottom of the panel, as that would be most consistent with UWP design guidelines. GridView also has a FooterTemplate, which allows you to add some XAML in the footer of the whole GridView (but not directly after the items).
If you still want to have the add item as part of the GridView contents, you will really need to use the fake item and a DataTemplateSelector. This solution is not very clean, but probably is the only simple way.
I tried to do something similar for my own app too, but there really isn't an obvious way to achieve it. A little background on what my app does: it's a flashcard app that displays decks of card in a gridview on the homepage, with an add button being at the front of the gridview. This is what I did:
for my deck class, I gave it a bool attribute isButton
in the observablecollection of decks, set the first item's isButton to true
make two datatemplates for the gridview (deck and button) and make a data template picker for the gridview, and check the isButton attribute
if isButton is true, the template picker will use the button template
otherwise use deck template

How to fix Listview ScrollViewer scrolling in PivotItem changing

I have a ListView in PivotItem and my pivot contains 3 pivot items. Each Piovt Item contain ListView. I want to disable scrolling on all the ListViews while user changing the Pivot Item swiping left/right. Currently while swiping left/right the pivot item is in changing mode and also my ListView scrolls. I have tried ManipulationStarted and ManipulationCompleted events but it is not working? Is there a way to achieve this? What I want is the same behavior of WP 8.1 email app, while swiping left/right it disables listview view scrolling.
<Pivot Grid.Row="1">
<PivotItem Margin="0" >
<PivotItem.Header>
<TextBlock Text="web" />
</PivotItem.Header>
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Margin="19,0,19,15"
Style="{StaticResource PhoneAccentTextSmallStyle}"
Visibility="{Binding CountryFacetCurrentlyShowing,Converter={StaticResource empltyStringToVisibilityConverter}}"
Text="{Binding CountryFacetCurrentlyShowing}"></TextBlock>
<!-- Search List Items -->
<ListView Grid.Row="2" x:Name="grdSearchResults" Width="{Binding ElementName=searchView,Path=ActualWidth}" ItemsSource="{Binding SearchedMembers}"
Visibility="{Binding ElementName=btnGridView,Path=IsEnabled,Converter={StaticResource boolToVisibiliytConverter}}"
LayoutUpdated="grdSearchResults_LayoutUpdated"
SelectedItem="{Binding SelectedMember,Mode=TwoWay}"
SelectionMode="{Binding ListViewMode}"
ItemTemplate="{Binding ItemTemplate}"
ItemContainerStyle="{StaticResource ListViewItemStyle99}">
</ListView>
<!-- Search Grid Items -->
<GridView Grid.Row="2" x:Name="grdSearchResults1" Width="{Binding ElementName=searchView,Path=ActualWidth}" ItemsSource="{Binding SearchedMembers}"
Visibility="{Binding ElementName=btnListView,Path=IsEnabled,Converter={StaticResource boolToVisibiliytConverter}}"
Margin="13,0,13,0" SelectedItem="{Binding SelectedMember,Mode=TwoWay}"
LayoutUpdated="grdSearchResults_LayoutUpdated"
SelectionMode="{Binding ListViewMode}"
ItemContainerStyle="{StaticResource GridViewItemStyle99}"
ItemTemplate="{StaticResource SearchGridItemDataTemplate}">
<!--<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="HorizontalContentAlignment" Value="{Binding DataContext.ItemWidth, Mode=OneWay, ElementName=searchView}"></Setter>
</Style>
</GridView.ItemContainerStyle>-->
</GridView>
<TextBlock Margin="19,10" Text="No matches found." FontSize="16" x:Name="lblNoConten" Foreground="DarkGray" Visibility="{Binding NoContentVisibility}"></TextBlock>
</Grid>
</PivotItem>
<PivotItem Margin="0">
<PivotItem.Header>
<TextBlock Text="local" />
</PivotItem.Header>
</PivotItem>
</Pivot>
Fixed this problem. I was using a default ListView style(which contains nothing new) in my resources and that was causing the problem after removing default style from my resources it works :). Do not know why it was causing the issue.

ListView padding on last item

I have a ListViewdefined in a Grid like this:
<Border BorderThickness="1" Grid.Row="1" VerticalAlignment="Top" Margin="0,0,0,50" BorderBrush="Gray">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<TextBlock Text="Test" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
<ListView
Grid.Row="1"
ItemsSource="{Binding MyItems}"
Padding="40,40,40,40"/>
</Grid>
My problem is that I want the last item of the listview to be 40 pixel away from listView's bottom, but my code is not working, the top padding is ok, but bottom has no effect. That is like adding a blank item on the beginning and the end of the listview but that would be a stupid thing to do.
You can put the ListView inside of another Scrollviewer and pad the ListView itself.

ScrollViewer not to scroll when content does not exceed parent's height

In this XAML I can scroll Contents grid up and down a bit even though it does not exceed the ScrollViewer height.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="80" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid x:Name="Controller" Grid.Row="0">
<controls:SearchField x:Name="Searcher" />
</Grid>
<ScrollViewer x:Name="Scroller" Grid.Row="1">
<ScrollViewer.Content>
<Grid x:Name="Contents">
<TextBlock Text="HI" />
</Grid>
</ScrollViewer.Content>
</ScrollViewer>
</Grid>
I guess it is a standard behavior of some kind but I don't like it too much. It it possible to make ScrollViewer not to scroll it's contents if they don't exceed ScrollViewer's height?

grid inside scrollviewer in windows phone 7.1

i need a registeration form within my application, i need scrolling so i did the following
<ScrollViewer VerticalScrollBarVisibility="Visible" Height="780" MaxHeight="1800"
MaxWidth="477" VerticalAlignment="Top">
<ScrollViewer.Content>
<Grid Width="477" Height="728" MaxHeight="1800">
<!-- .......Form's Elements..... -->
</Grid>
</ScrollViewer.Content>
</ScrollViewer>
there is no scrolling, what am i missing?
You shouldn't set the height properties when working with a ScrollViewer. If you strip it down to just the following and it still doesn't work, then it is something else in your project that is preventing it to work.
<ScrollViewer>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="Hello" FontSize="320" />
<TextBlock Grid.Row="1" Text="World" FontSize="320" />
</Grid>
</ScrollViewer>
Remove the ScrollViewer.Content - part, I have an app that has this structure and it works fine:
<ScrollViewer x:Name="ContentScrollViewer" Margin="0,0,0,8">
<Grid Height="562">
<!-- My elements -->
</Grid>
</ScrollViewer>
Your scrollviewer has a height of 780 and your grid is only 728. Why would there be any scrolling? You'll only be able to scroll if the grid is higher than 780.