I have a problem scrolling vertically within a data bound pivot page (WP 7.1).
I have tried the different solutions posted here and on MSDN, but none of them seem to work for me..
I have a list
of News objects in an ObservableCollection that I am displaying in a pivot page. So far so good...
I want to be able to scroll the main text of the news item, but have the menu and headline stationary on the page.
I have tried making a grid and surrounding the scrollable content by a Listbox and now a ScrollViewer, but I am not able to scroll on the page.. When I try scrolling, I can scroll a couple of lines of text, and then the text reverts to the original position. Very frustrating!!!
The code I have tried is this:
<!--Pivot Control-->
<controls:Pivot x:Name="PivotNews"
Grid.Row="2"
ItemsSource="{Binding NewsCollection}" >
<controls:Pivot.HeaderTemplate>
<DataTemplate>
<!--<TextBlock Text="Seneste nyheder" />-->
</DataTemplate>
</controls:Pivot.HeaderTemplate>
<controls:Pivot.ItemTemplate>
<DataTemplate>
<StackPanel>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<!--<RowDefinition Height="*" />-->
</Grid.RowDefinitions>
<Grid x:Name="HeaderLine"
Grid.Row ="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Source="{Binding ImageUri}"
Grid.Column="0"
Height="150"/>
<TextBlock Text="{Binding Header}"
FontWeight="ExtraBold"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
TextWrapping="Wrap"
Grid.Column="1"
Margin="10,0,0,10"/>
</Grid>
<ScrollViewer x:Name="ScrollViewerNews" Grid.Row="1">
<StackPanel>
<TextBlock Text="{Binding SubHeader}"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontWeight="Bold"
TextWrapping="Wrap" />
<TextBlock Text="{Binding MainText}"
TextWrapping="Wrap" />
</StackPanel>
</ScrollViewer>
</Grid>
</StackPanel>
</DataTemplate>
</controls:Pivot.ItemTemplate>
</controls:Pivot>
Just remove first StackPanel in your ItemTemplate.
When you use StackPanel, it has it's own height, that does not depend on Page height, and row height value "*" tries to fit in the available space, that is in this case bigger, than the pages height.
Related
I have the following MainPage.xaml
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<RelativePanel>
<Button Name="btnHamburger" FontFamily="Segoe MDL2 Assets" Content="" Click="HamburgerButton_Click" RelativePanel.AlignLeftWithPanel="True"/>
<TextBlock Name="PageTitle" Text="Title" FontSize="24" FontWeight="Bold" RelativePanel.AlignHorizontalCenterWithPanel="True"/>
</RelativePanel>
<SplitView Name="MySplitView" Grid.Row="1" DisplayMode="Overlay" OpenPaneLength="170" CompactPaneLength="56" HorizontalAlignment="Left">
<SplitView.Pane>
<StackPanel Orientation="Vertical">
<TextBlock Text="Skyron Image" FontSize="16" VerticalAlignment="Center" />
<ListBox SelectionMode="Single" Name="IconsListBox" SelectionChanged="IconsListBox_SelectionChanged">
</ListBox>
</StackPanel>
</SplitView.Pane>
<SplitView.Content>
<Frame Name="MyFrame" />
</SplitView.Content>
</SplitView>
</Grid>
It gives me a navigation menu system. When I click on of the navigation links, I load the corresponding page into the Frame MyFrame.
This is my HomePage
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Home page" Name="tbHome" />
</Grid>
As you can see, I've tried to achieve my desired outcome by setting HorizontalAlignment="Stretch" on the grid and setting a column definition to auto.
I guess the issue is that I don't have enough content in the grid to make it full screen. This is what I currently have:
I have made the homepage background blue - as you can see, it doesn't fill the entire screen.
How can I achieve what I want, without setting a width on the Grid - as this won't work with different sized phones/screens.
EDIT:
I've just relised the width of the content is being controlled by the OpenPaneLength="170" setting. Why does this effect the content and how can I stop it effecting the content width?
Set the HorizontalAlignment property of the SplitView to "Stretch" instead of "Left".
I've got a XAML page which is broken down with a grid as follows:
<Grid Background="Green">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
</Grid>
The first and third row contain a TextBlock each and are set to auto-resize to their height and the ListView is contained in the middle row and it is suppose to stretch within the area.
The ListView appears to be resized based on the number of items rather than the available visible area that should be allocated to the middle row.
This has 2 side effects:
I can't scroll to view the other items
It pushes the TextBlock in the third row out of the screen.
If I set a specific height on the ListView, it works as expected but I want my ListView to use the entire area of the screen between the top and bottom rows.
It displays as expected in the IDE, but no data is loaded but I can clearly see my top and bottom row (in green) and I can see the ListView is stretched between these 2 rows.
I've used this numerous times in the past but with a universal app for Windows 10, so I'm wondering if this is a new behaviour I'm not aware of or is this a bug?
This is full code without the DataTemplate for clarity sake. Just to be clear, my DataTemplate is displaying correctly, but I just can't scroll as there is no scrollbar since the listview is stretched based on the items, rather than being restricted to the available area of the middle row.
<Grid Background="Green">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="Top Row" />
<ListView ItemsSource="{Binding Items}"
Grid.Row="1"
Background="Red">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
....
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<TextBlock Text="bottom row" Grid.Row="2"/>
</Grid>
You need to wrap your ListView in a ScrollView. This will fill the empty area and add a scroll bar as the list overflows the empty area.
I figured out the problem. It isn't a change in behaviour or a bug!
As someone mentioned that they tried to reproduce the problem and couldn't, I decided to do the same.
When I put my grid and ListView directly on the MainPage, I couldn't reproduce it.
When I put my grid and ListView on a sub-page (i.e. GridPage) and loaded it into the frame contained on the MainPage, I couldn't reproduce it
and that's when the penny dropped!!
In my code, I used (for the first time) a SplitView and this SplitView was contained in a grid with 2 rows and stupidly, both rows were set to "Auto" when I should have set the first one to Auto for my hamburger menu, logo and title and the second one should have been set to '*'.
The second I changed my second row to '*', the problem got sorted. It had nothing to do with the Grid Page which contained the grid I originally posted problem with.
<Grid Background="{ThemeResource FocusVisualWhiteStrokeThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
Here is the full code:
<Grid Background="{ThemeResource FocusVisualWhiteStrokeThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Border Background="White"
Grid.Row="0"
Grid.Column="0"
Margin="0,10,0,10">
<ToggleButton Style="{StaticResource SymbolButton}"
Foreground="{ThemeResource ApplicationForegroundThemeBrush}"
FontSize="{ThemeResource ControlContentThemeFontSize}"
Command="{Binding HamburgerCommand}" >
<FontIcon x:Name="Hamburger"
FontFamily="Segoe MDL2 Assets"
Glyph=""
Foreground="#ff6600" />
</ToggleButton>
</Border>
<Border Background="White" Grid.Row="0"
Grid.Column="1" Margin="10,0,0,0">
<Image Stretch="Fill" Source="{Binding SelectedSection,
Converter={StaticResource SectionImageConverter}}"
Height="20" Width="20" />
</Border>
<Border Background="White"
Grid.Row="0"
Grid.Column="2"
Margin="10,0,0,0">
<TextBlock x:Name="Header" Text="{Binding SelectedSection,
Converter={StaticResource
SectionTitleConverter}}"
Style="{StaticResource TagLineTextStyle}"
Foreground="#ff6600"
VerticalAlignment="Center"
Margin="10,0,0,0"/>
</Border>
</Grid>
<SplitView x:Name="Splitter"
IsPaneOpen="{Binding IsPageOpen}"
DisplayMode="Inline"
Grid.Row="1">
<SplitView.Pane>
<ListBox x:Name="SectionControl" SelectionMode="Single"
ItemsSource="{Binding Sections}"
HorizontalAlignment="Left"
Background="White"
BorderThickness="0"
VerticalAlignment="Top"
SelectedItem="{Binding
SelectedSection, Mode=TwoWay}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Converter={StaticResource
SectionImageConverter}}"
Height="17" Width="17"/>
<TextBlock Text="{Binding
Converter={StaticResource
SectionTitleConverter}}"
Margin="20,0,0,0"
Foreground="#ff6600" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="SelectionChanged">
<Core:InvokeCommandAction Command="{Binding
ItemClickCommand}"
CommandParameter="{Binding SelectedSection}" />
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</ListBox>
</SplitView.Pane>
<SplitView.Content>
<Frame x:Name="SectionFrame"/>
</SplitView.Content>
</SplitView>
</Grid>
Thanks again for the feedback/help. Much appreciated!
I made a popup control that can accept any view of type FrameworkElement. In addition, you can provide a view model, which will be bound to the DataContext of the child view being provided. Everything works, but it takes a couple of seconds to render the data. The view model has an ObservableCollection that contains about 300 items. So in all honesty, 300 items shouldn't cause any issues.
There is no lag what so ever, If I extract the xaml from the popup to a regular page.
So, is there something inside a Popup control that happens when it's Child content property is being set, that would cause such a delay? Because this is blowing my mind at the moment.
Thanks in advance!
[Update]
As requested, the XAML that forms the child content of the tool window:
<UserControl
x:Class="App.Controls.ContactSelector"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
mc:Ignorable="d" x:Name="contactSelector"
DataContext="{Binding ContactSelectorViewModel,Source={StaticResource Locator}}">
<Grid HorizontalAlignment="Stretch" Style="{StaticResource BaseGridStyle}">
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListView Grid.Row="0" ItemsSource="{Binding ContactCollection}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Margin="12">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<!--<Image Margin="0,0,10,0" Grid.Row="0" Grid.Column="0"
Source="{Binding Thumbnail}" MaxHeight="35"
Visibility="{Binding Thumbnail, Converter={StaticResource ObjectNullToVisibilityConverter}}" />-->
<!--<Image Margin="0,5,5,5" Grid.Row="0" Grid.Column="0" MaxHeight="35"
Source="ms-appx:///Assets/Images/Contact.png"
Visibility="{Binding Thumbnail, Converter={StaticResource InverseObjectNullToVisibilityConverter}}" />-->
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding FullName}"
VerticalAlignment="Center"
Style="{StaticResource TextBlockMedium}" />
<!--<Grid Grid.Row="1" Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ItemsControl Grid.Row="0" ItemsSource="{Binding MobileNumbers}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="10,5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Margin="0"
Text="{Binding Number}"
HorizontalAlignment="Stretch"
Style="{StaticResource TextBlockMedium}">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Tapped">
<core:InvokeCommandAction
Command="{Binding DataContext.SelectContact, ElementName=contactSelector}"
CommandParameter="{Binding}" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</TextBlock>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>-->
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
<!--<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Border>
<TextBlock Text="{Binding Key}"
VerticalAlignment="Center" HorizontalAlignment="Center"
Style="{StaticResource TextBlockMedium}"
Padding="5" Margin="5" FontWeight="SemiBold" />
</Border>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>-->
</ListView>
</Grid>
</UserControl>
So I have commented out the entire section of the ItemsControl, but this did not solve the problem. When the Popup opens, it still takes quite a while to show the containing items.
It isn't slow when it's scrolling, it's slow in rendering the initial items.
The problem is in the ItemsControl which displays the MobileNumbers collection. You should not have an ItemsControl as an ItemTemplate for another ItemsControl (in your case, the ListView). You can do that only when you display small amount of items.
Because of this your MobileNumbers items are not virtualized and this is where the performance problem comes from, as all the items need to be displayed to render the item template.
You can try creating a flat list of objects, and then use ItemTemplateSelector to display different item templates for different types. For example you could have the following ObservableCollection as the ItemsSource:
Header
Contact info
Mobile number1
Mobile number2
Header
Contact info
Mobile number
etc.
I am trying to migrate my old app to Windows 10 and I am facing an issue with Grid. I created a Grid in XAML page with WebView and ListView inside it in 2 different rows. Now problem is that it appears fine in Local Machine(Laptop) but when I check the same in Windows Phone, it doesn't look good(image, text looks very large). Please find my XAML code and DataTemplate for ListView below. I am aware that RelativePanel will save my day, but can anyone update my code and suggest me so that I can use the same on each page as my app uses ListView inside Grid very often.
XAML CODE
<Grid x:Name="LayoutRoot" Background="{StaticResource AppBackGroundColor}">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<WebView Grid.Row="0"
x:Name="webView"
DefaultBackgroundColor="#388941"
IsHitTestVisible="False"/>
<ListView x:Name="loginandRegisterOptionslist"
Margin="0,10,0,0"
Grid.Row="1"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ItemContainerStyle="{StaticResource GenericListViewContainerStyle}"
ItemTemplate="{StaticResource WelcomePageListItemTemplate}"
VerticalAlignment="Bottom"
SelectionMode="Single"
/>
</Grid>
Data Template for above ListView
<DataTemplate x:Key="WelcomePageListItemTemplate">
<Grid Margin="0,2,0,2"
Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Width="80"
Height="60"
Name="img1"
Stretch="Uniform"
Margin="4,0,4,0"
Grid.Column="0"
Source="{Binding IMAGE_URL}"></Image>
<StackPanel Grid.Column="1"
Margin="0,8,0,8">
<TextBlock Text="{Binding TITLE}"
Margin="2"
Style="{StaticResource HeaderContentStyle}" />
<TextBlock Text="{Binding VALUE}"
Margin="2"
Style="{StaticResource DescriptionContentStyle}" />
</StackPanel>
</Grid>
</DataTemplate>
There are some solutions that you might want to try out:
Put your datatemplace inside an User Control, use Adaptive Trigger to custom the size of image and text according to difference screen sizes.
Use difference XAML View for difference device families
When launching the app, detect the device family, set the correct value for size binding base on that information
I have this very simple XAML window:
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<ContentControl Content="{Binding Path=Item}" ContentTemplate="{StaticResource aaaa}" Grid.Row="1"/>
<ListView ItemsSource="{Binding Path=ItemList}" ItemTemplate="{StaticResource aaaa}" HorizontalContentAlignment="Stretch"/>
</Grid>
where the ContentControl and the ListView have the same template:
<DataTemplate DataType="{x:Type src:ItemType}" x:Key="aaaa">
<Grid ShowGridLines="True" Height="30">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Name="resizinglabel" Text="this is a very long text that has to be trimmed" />
<TextBlock Name="fixedLabel" Text="always to the left" Grid.Column="1" Background="Red" />
</Grid>
</DataTemplate>
But when I resize the window the listview seems to have a weird behaviour:
Before the critical point of resizing:
After The critical point of resizing:
in a few words i want the right label to be always visible on the right. I tried also with the isSharedSizeScope property but id doesn't works... So the question is: what I have to do to make the listview behaving like the content control?
Thanks in advance!
ListViews will automatically add ScrollBars if their content is too large to fit on the screen. Disable the Horizontal ScrollBar and it should work.
<ListView ScrollViewer.HorizontalScrollBarVisibility="Disabled" />