My LongListSelector is not scrolling properly. When I scroll the list, it automatically reaching back to the top with its rubber band effect.
xaml is
<Grid x:Name="ContentPanel" Height="2000">
<toolkit:LongListSelector x:Name="ItemList" DataContext="Item" IsFlatList="True" StretchingBottom="LoadMoreData">
<toolkit:LongListSelector.ItemTemplate>
<DataTemplate>
<Grid Tag="{Binding ItemID}" Loaded="Grid_Loaded" MaxWidth="361" MaxHeight="100">
// some xaml code
</DataTemplate>
</toolkit:LongListSelector.ItemTemplate>
</toolkit:LongListSelector>
</Grid>
can anyone help me ?
thanku
It's not scrolling correctly because you set the Height of the parent Grid to 2000. This causes the LongListSelector to take as much space as it may need as long as it's less than 2000 and only then starts scrolling. Considering you only have 800 (or a bit more) of height, you don't see the scrolling properly.
Related
To make a chat page, I followed an example I found that sets the ListView rotation to 180, so the list builds from the bottom and then set things in the DataTemplate to rotate 180, so the items will be upright. It's a great solution, but when the keyboard opens, the ListView gets shorter which causes a redraw. During the redraw, the ListView initially appears with rotation 0 and I see an animation as if RotateTo(360) is being called. After initially displaying, I get to watch the list view rotate around in full circle. Click off the message editor, and the ListView gets taller, and it does it again.
Has anyone seen this?
Here's what the Xaml looks like. I can't make a gif of what it looks like, but imagine watching:
MessageList.Rotation = 0;
MessageList.RotateTo(360, 500, Easing.Linear);
each time the keyboard shows and hides, and you'll get the idea...
<ListView
X:Name="MessageList"
AbsoluteLayout.LayoutFlags="All"
AbsoluteLayout.LayoutBounds="0,0,1,1"
Rotation="180"
ItemsSource="{Binding ChatMessages}"
SelectionMode="None"
HasUnevenRows="True"
SeparatorColor="Transparent">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Frame
BackgroundColor="LightGray"
FlowDirection="LeftToRight"
Rotation="180"
Padding="10"
HasShadow="false"
Margin="80,2,0,5">
<Label Text="{Binding ChatText}"/>
</Frame>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I followed the same tutorial you mentioned and you are probably using a ContentPage renderer to handle your keyboard layout updates on iOS. If you check the sample project https://github.com/rdelrosario/ChatUIXForms you'll notice he resizes the keyboard ContentView with a ContentView renderer for the Editor box at the bottom using the Margin property, rather than the entire ContentPage. Which doesn't trigger the above issue.
What I wound up doing was to make a custom ListView renderer that was keyboard aware in iOS and sets a translation X to move the top of the listview up when the keyboard appears and back down when it goes away. As a result, the listview is not getting resized, and thus does not redraw.
It may be messy, but it makes it work...
I have a UserControl that needs to contain a bunch of controls on top and a LongListSelector below them. Total height of the whole UserControl may (and almost always will) exceed the screen height and in that case a whole UserControl must be scrollable.
My current setup is as follows:
<staff:UserContentControl
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:MyApp.Controls"
xmlns:staff="clr-namespace:MyApp.Helpers"
x:Class="MyApp.Controls.RemoteHomePage"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}">
<ScrollViewer>
<ScrollViewer.Content>
<StackPanel>
<TextBlock Txt="Text1" Sign="#" />
<TextBlock Txt="Text2" Sign="#" />
<controls:Divider />
<TextBlock Txt="Text3" Sign="~" />
<TextBlock Txt="Text4" Sign="~" />
<controls:TextDivider Text="Divider text" />
<phone:LongListSelector ItemsSource="{Binding Items}">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}" />
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
</StackPanel>
</ScrollViewer.Content>
</ScrollViewer>
</staff:UserContentControl>
This solution satisfies my needs but also there's a big problem: currently LongListSelector takes really a lot of time to load when amount of items it contains is reasonably large. It takes 8 seconds to process 300 items and during that time the whole UI is blocked. If I remove everything but LongListSelector, like so:
<staff:UserContentControl
...>
<phone:LongListSelector ItemsSource="{Binding Items}">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Title}" />
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
</staff:UserContentControl>
then LongListSelector loads almost immediately even with significantly larger amount of items. But obviously I need those other controls above it so the question is what can I do solve this issue?
(Also related question: I was worried that LongListSelector inside ScrollViewer could cause double scrolling or something like that but eventually everything turned out just fine in this regard. I'm not sure if LongListSelector somehow knows that it is inside other scrollable control or if something else happens that I'm not aware of. Some explainantion why it works fine, although very slow, would be much appreciated.)
Don't use scroll viewer since it will make the longlistselector think it has an infinitely tall screen available and render all its items.
Instead to solve your usecase use the Header and Footer properties to add data above or below your list items.
You can't force ScrollViewer to virtualize LongListSelector items.
So you need to mimic it behaviour by LongListSelector only.
Make the first item contains all you required elements form StackPanel (1'st itemtemplate). And other elements will be basic LongListSelector elements (2'nd itemtemplate).
Here is explanation how to set different templates to the items: Styling a selected ListViewItem in Windows 8 CP
I am working on an application which includes a registration form. The form contains multiple text entry boxes, and so a ScrollViewer is used to allow them all to be displayed on one page.
The following is a stripped down example of the XAML code I am using:
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="SCROLLVIEWER TEST" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="registration" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<ScrollViewer Grid.Row="1">
<StackPanel>
<TextBlock Text="Hello" Margin="12,0,0,0"/>
<TextBox />
<TextBlock Text="Hello1" Margin="12,0,0,0"/>
<TextBox />
<TextBlock Text="Hello2" Margin="12,0,0,0"/>
<TextBox />
<TextBlock Text="Hello3" Margin="12,0,0,0"/>
<TextBox />
<TextBlock Text="Hello4" Margin="12,0,0,0"/>
<TextBox />
<TextBlock Text="Hello5" Margin="12,0,0,0"/>
<TextBox />
<TextBlock Text="Hello6" Margin="12,0,0,0"/>
<TextBox />
<TextBlock Text="Hello7" Margin="12,0,0,0"/>
<TextBox />
<TextBlock Text="Hello8" Margin="12,0,0,0"/>
<TextBox />
<TextBlock Text="END" Margin="12,0,0,0"/>
<TextBox />
</StackPanel>
</ScrollViewer>
</Grid>
(Note that the ScrollViewer is inside a grid cell, which means that the title panel should stay OnScreen at all times)
The scrolling works perfectly fine, so that is not an issue. However, when the user selects a TextBox to enter data (i.e. the soft keyboard opens), the system pushes the content of the entire page around (including the registration title panel), which is not expected behaviour.
[See the People app on Windows Phone and try adding a new contact. This contains a similar structure, but the ScrollViewer behaves correctly by only pushing content in the scrollviewer up]
Test Cases
Select a TextBox that is visible near the top of the screen, to open the keyboard.
Attempt to scroll to the bottom of the page with keyboard open.
Items at the bottom of the page are unreachable.
or
Select a TextBox that is visible near the bottom of the screen.
Content of entire page is pushed up.
Attempt to scroll to the top of the page with keyboard open.
Items at the top of the page are unreachable, and title panel never comes back into view until keyboard is closed.
Any help on resolving this issue would be appreciated. Thanks.
The problem is that the ScrollViwer height is not modified after the keyboard appears so it becomes clipped. One solution would be to modify the height of the scrollviwer (according to the keyboard height) and then reposition it (this might give you some headaches).
Another problem is knowing when the keyboard appears - you could register for the GotFocus/LostFocus events on all your TextBoxes but it's not a great solution. This might help you: http://blogs.msdn.com/b/jaimer/archive/2010/11/05/guessing-if-the-sip-is-visible-in-a-windows-phone-application.aspx
Hope this helps a little :)
I think you can solve this by coming at the problem from another angle. The phone will scroll up the page so that the SIP (software keyboard) never covers up the TextBox which has focus.
However you can force the SIP to hide by detecting touch events on the top element contained in your ScrollViewer, e.g.:
<ScrollViewer Grid.Row="1">
<StackPanel ManipulationDelta="OnScrollViewerGridManipulationDelta">`
Then, by giving the focus to a hidden button (0x0 pixels in size) this will force the SIP to close. Then it will be possible for your users to scroll up and down the scrollviewer as expected...
private void OnScrollViewerGridManipulationDelta(object sender, System.Windows.Input.ManipulationDeltaEventArgs e)
{
// This will hide the SIP if it is currently showing.
// We can't do this directly, but we can force this by taking focus away from any of the TextBoxes that may have it.
this.hiddenButton.Focus();
}
I've had the same issue with an app I've developed and the way I dealt with it was to find out the auto height of the panel containing the input textboxs and then manually set the height and add approximately 400 - 500 px to the bottom to make it scroll nicely. The effect is quite smooth and will not make your UI look "hackish" IMHO.
In your case you will have to find out the automatic height of the LayoutRoot Grid and then on RowDefinitionof Row 1 set the height manually - remembering to add an extra 400px (or whatever looks appropriate in your situation).
For ease of input I then handled each OnKeyDown event of each TextBox to change the focus to the next TextBox upon hitting Enter. On the last TextBox I set the focus to this.focus() which sets focus to the Page and hides the SIP.
Have a look at my small library please - https://siphelper.codeplex.com/
It modifies height of scrollviewer and content can be scrolled to the topmost/bottommost point.
If you have any suggestions - feel free to contact me.
I am using a scrollviewer to show contents, and added a "DoubleTap" event to the scrollviewer. In the doubleTap event I want to make the scrollviewer automatically scroll up to the top of the scrollviewer, but I can't find any property to control the scrollviewer. any thoughts?
Thanks in advance.
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="0,0,0,0">
<ScrollViewer x:Name="scrollViewer2" Height="auto">
<toolkit:GestureService.GestureListener>
<toolkit:GestureListener DoubleTap="GestureListener_DoubleTap"/>
</toolkit:GestureService.GestureListener>
<StackPanel x:Name="stackPanel2" Height="auto">
<!--contents-->
</StackPanel>
</ScrollViewer>
</Grid>
You don't have properties, but you have two methods for this: ScrollToVerticalOffset (to scroll vertically) and ScrollToHorizontalOffset (to scroll horizontally).
So in your case, this code should do the trick:
this.scrollViewer2.ScrollToVerticalOffset(0);
Also note that it is going to be obsolete or maybe unavailable after 8.1.
Use
this.scrollViewer2.ChangeView(0, 0, 1);
instead.
You can use this code:
this.scrollViewer2.ChangeView(null, 0, null);
i have a panorama view and would like, once i reached the end of my view, to be able to continue to the front (having my background image with matching ends) so that it looks like it is continuous, but when i go from front to end or vice-versa, as i slowly scroll left/right i can see the other end of my picture compressed(and once i get to that panoramaItem, it is decompressed looking natural).
My background is 1024/800 so it is ok by microsoft and my panormala code is :
<controls:Panorama>
<controls:Panorama.Background>
<ImageBrush ImageSource="/_Assets/Layout/pasta-bg-3.jpg"/>
</controls:Panorama.Background>
<!--Panorama item one-->
<controls:PanoramaItem Header="a" Orientation="Horizontal">
</controls:PanoramaItem>
<controls:PanoramaItem Header="a" Orientation="Horizontal">
</controls:PanoramaItem>
<controls:PanoramaItem Header="a" Orientation="Horizontal">
</controls:PanoramaItem>
</controls:Panorama>
Am i doing something wrong?
You'll need to adjust the size of your panorama background image depending on the number (and width) of panorama items youre using to achieve this effect.
I guess proper values for the Width property of the panorama Items , solves your problem.