when keyboard is show, scrolling is limited - windows-phone-7

I have a problem with scrolling in windows phone. I have a lot of elements on page so to add ability to scroll I put this on ScrollViewer. Hovewer, when I foucesd on some text block and the keyborad shows up, the scroll in working but it cuts the top and bottom of the page so it's can't be reach by user. Have you had similar problem with your apps and know how to fix this ?
I wil be really grateful for any help
Link to image when I put screenshot with my problem
The picture contains four screenshots:
1) The top of the page
2) The bottom of the page
3) Focus on the first textbox
4) The area on the page which can be reached when focus is set to the first TextBox
The last one picture present the are which can be rached when focus is set to the first textbox. As you can see I can't get to the textboxes below Field 7 when keybord is shown.
What I need is the ability to scroll and to reach all elements when the keybord is shown.
Do you know how to resolve my poblem
It's my xaml code:
<phone:PhoneApplicationPage
x:Class="PhoneApp6.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<ScrollViewer Grid.Row="1" Height="600" Margin="12 0">
<StackPanel>
<StackPanel>
<TextBlock Text="Name 1" />
<TextBox />
</StackPanel>
<StackPanel>
<TextBlock Text="Name 2" />
<TextBox />
</StackPanel>
<StackPanel>
<TextBlock Text="Name 3" />
<TextBox />
</StackPanel>
<StackPanel>
<TextBlock Text="Name 4" />
<TextBox />
</StackPanel>
<StackPanel>
<TextBlock Text="Name 5" />
<TextBox />
</StackPanel>
<StackPanel>
<TextBlock Text="Name 6" />
<TextBox />
</StackPanel>
<StackPanel>
<TextBlock Text="Name 7" />
<TextBox />
</StackPanel>
<StackPanel>
<TextBlock Text="Name 8" />
<TextBox />
</StackPanel>
<StackPanel>
<TextBlock Text="Name 9" />
<TextBox />
</StackPanel>
<StackPanel>
<TextBlock Text="Name 10" />
<TextBox />
</StackPanel>
<Button>Submit</Button>
</StackPanel>
</ScrollViewer>
</Grid>
</phone:PhoneApplicationPage>

This is a known issue and is caused by the SIP changing the viewable area of the screen. The link David Gorden mentioned does help, but you actually need to change the height of the scrollviewer to achieve perfect results. To make things a little more complex WP does not trigger an event for when the SIP is visible! So you need to hook into the GotFocus/LostFocus events.
Edit your scrollviewer so it looks something like this:
<ScrollViewer x:Name="_scrollViewer"
VerticalAlignment="Top"
GotFocus="UIElement_OnGotFocus"
LostFocus="UIElement_OnLostFocus"
... bla bla
Now add the following in the codebehind:
private bool _isHdDevice;
private int _sipHeight;
private double _origHeight;
// Constructor
public MainPage()
{
InitializeComponent();
// todo - cater for landscape mode or sip scopenames that require extra space (predictive text and cut&paste icon)
var deviceWidth = this.ActualWidth;
_isHdDevice = (deviceWidth > 500);
_sipHeight = _isHdDevice ? 540 : 375;
_origHeight = _scrollViewer.Height;
}
private void UIElement_OnGotFocus(object sender, RoutedEventArgs e)
{
double height = this.ActualHeight - _sipHeight - TitlePanel.ActualHeight;
_scrollViewer.Height = height;
// the following lines are crucial otherwise a black band could appear above the SIP
App.Current.RootVisual.RenderTransform = new CompositeTransform();
this.UpdateLayout();
}
private void UIElement_OnLostFocus(object sender, RoutedEventArgs e)
{
_scrollViewer.Height = _origHeight;
}
This is basically resizing the scroll area when the sip (keyboard) is in view. You will need to add more code to cater for things like screen rotation, scopename associated to the textbox, and cut&paste icon if in view. But this will get you going and does the difficult bit.
Please mark as answered if it helped fix the issue.

If I understand this correctly, I was having a similar problem in my own app with an inability to scroll downward to the lowest texboxes while the keyboard is visible. Since I'm not all that clever, I solved it in the following way: a spacer that appears when the keyboard is up and disappears when it's not.
The textbox items for input in my scrollviewer are all in wrappanels, to keep things tidy. Below the last wrap panel, I added another, empty wrap panel, named "spacer" with a height of 120. It is set to visibility.collapsed by default.
As part of the gotfocus event handler for each of the textboxes in the wrap panel, I set spacer to visible. That allows for scrolling all the way to the last wrappanel/textboxes in my scroll viewer while the keyboard is up.
As a part of my lostfocus event handler for each of the textboxes, spacer's visibility is set back to "collapsed." That way, when there's no keyboard up, the scrollviewer doesn't have a big, funky, empty space at the bottom.
This may not be so elegant, but it's easy and works pretty well for me. I have not yet encountered any problems with it, though that doesn't mean there may not be something I've missed.

Related

Keyboard hides the focused textbox

I have problems with the SIP (keyboard). It hides the currently focussed textbox.
I have a form with some numbers of TextBoxes and I change focus by tapping ↲ on the SIP.
But then the keyboard hides the textbox...
all my textboxes are in StackPanel and around by
Is this a known problem? Is there a solution?
<ScrollViewer x:Name="Scroller" Grid.Row="1">
<StackPanel Orientation="Vertical">
<TextBlock Text="Name"/>
<TextBox x:Name="txtName" />
<TextBlock Text="Email"/>
<TextBox x:Name="txtEmail"/>
<TextBlock Text="Phone"/>
<TextBox x:Name="txtPhone" />
<TextBlock Text="Adress"/>
<TextBox x:Name="txtAddress" />
</StackPanel>
</ScrollViewer>
keep your code inside the <ListBox>. It will not hide then.

Getting Data from a Data Bound Map View Item's Context Menu

I'm writing a Windows Phone application that shows a number of locations on a map. These positions have phone numbers, twitter accounts and websites associated with them.
What I want to do is add a context menu to the items that allows the user to open the websites, view twitter or call the phone number. However, with a MapItemsControl their is no easy way to get the current item.
I am looking for some way to do this in as painless a way as possible.
Some code:
<mi:MapItemsControl x:Name="mapPins" ItemsSource="{Binding Pushpins}">
<mi:MapItemsControl.ItemTemplate>
<DataTemplate>
<mi:Pushpin Location="{Binding Location}">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu IsEnabled="{Binding ShowContext}" >
<TextBlock Opacity="{Binding Opacity, ElementName=image}" Text="Show Menu"/>
<TextBlock Opacity="{Binding Opacity, ElementName=image1}" Text="Open Webpage" Tap="EOpenWeb" />
<StackPanel Opacity="{Binding Opacity, ElementName=image2}" Orientation="Horizontal" Tap="ECallPhone">
<TextBlock Text="Call "/>
<TextBlock Text="{Binding Contact.FormattedPhone}"/>
</StackPanel>
<TextBlock Opacity="{Binding Opacity, ElementName=image3}" Text="On Twitter" Tap="EOpenTwitter" />
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
<StackPanel HorizontalAlignment="Stretch">
<TextBlock Foreground="{Binding Foreground}" Text="{Binding Name}" d:LayoutOverrides="HorizontalAlignment"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,-6" Visibility="{Binding ShowGlyphs}">
<TextBlock TextWrapping="Wrap" Text="{Binding HereNow}" Visibility="{Binding ShowHere}" VerticalAlignment="Center" FontSize="{StaticResource PhoneFontSizeMediumLarge}" HorizontalAlignment="Left" Height="36" Width="48" TextAlignment="Center"/>
<Image x:Name="image" Height="48" Opacity="{Binding HasMenu}" Source="locationGlyphs/appbar.book.open.png" Stretch="Fill"/>
<Image x:Name="image1" Height="48" Opacity="{Binding HasWeb}" Source="locationGlyphs/appbar.link.png" Stretch="Fill" Width="48"/>
<Image x:Name="image2" Height="48" Opacity="{Binding HasPhone}" Source="locationGlyphs/appbar.phone.png" Stretch="Fill" Width="48"/>
<Image x:Name="image3" Height="48" Opacity="{Binding HasTwitter}" Source="locationGlyphs/appbar.twitter.bird.png" Stretch="Fill" Width="48"/>
</StackPanel>
</StackPanel>
</mi:Pushpin>
</DataTemplate>
</mi:MapItemsControl.ItemTemplate>
</mi:MapItemsControl>
That details how the objects are drawn to the map. The Pushpins list is just an Observable Collection of my data.
If this was a ListBox I could simply use the SelectedItem or similar to resolve this, but that doesn't seem an option for MapItemsControl. Has anyone managed to do this successfully? How?
You need to somehow react to the tap on the pushpin. You have a contextmenu and you clearly need to go that way at the moment. needs to have a tap event handler attached:
<mi:Pushpin
Location="{Binding Location}" Tap="Pushpin_Tap">
Pushpin_Tap event handler needs to be managed similar to this:
private void Pushpin_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
var _ppmodel = sender as Pushpin;
ContextMenu contextMenu =
ContextMenuService.GetContextMenu(_ppmodel);
contextMenu.DataContext = _viewModel.Pushpins.Where
(c => (c.Location
== _ppmodel.Location)).FirstOrDefault();
// this way you can find which pushpin/position was tapped by finding the
// one which has the same location in your Pushpins observable collection
if (contextMenu.Parent == null)
{
contextMenu.IsOpen = true;
}
}
I wrote about showing a context menu on pushpin tap on my blog, so if you wish you can go and read the whole story there.

Text aligning of TextBlock in listbox in WP7

I'm having a problem aligning the text in my listbox. I'm basically trying to create listbox that works like a uitableview in iOS.
In the code below the left TextBlock is set up just how I want it, but I can't get the right TextBlock to behave like I want it. Right now the text is right aligned so that when the text is too long to fit on the screen it cuts off the text at the beginning and just shows the end of the text. What I want to happen is have the TextBlock right aligned so that is stretches from the right but have the text inside of if left aligned so that it shows the beginning of the text and cuts off the end of the text.
<phone:PhoneApplicationPage.Resources>
<Style x:Key="ListBoxItemStretchContentStyle" TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</phone:PhoneApplicationPage.Resources>
<ListBox Height="327" Margin="8,274,0,0" Name="myListBox" Width="442" ItemContainerStyle="{StaticResource ListBoxItemStretchContentStyle}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Title Text" HorizontalAlignment="Left" Name="cellTitle" />
<TextBlock Grid.Column="1" Text="This is some text that is too long to fit on the screen" HorizontalAlignment="Right" TextAlignment="Left" Padding="20,0,0,0" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
TextTrimming might be of help here.
After setting the TextWrapping="NoWrap" could you try TextTrimming="WordEllipsis". Then try, modifying the TextAlignment.
Hope that helps.
If I understand correctly, you could set the maxwidth parameter of the textblock to keep it from overlapping?
MaxWidth=""

Scroll PanoramaItem Header in 'wide' PanoramaItem

I'm interested in creating my own 'Hub' Panorama. I've gotten the 'wide' PanoramaItem working, but I'm trying now to mimic the behavior seen in the Marketplace hub, where the PanoramaItem Header scrolls as you move across the hub.
I'm looking for a way for it to smoothly animate to the end of the hub. Has anyone tried this before, or have any suggestions?
I'd imagine it would be something like this:
//OnPanoramaViewChanged
//get X location of viewport
//animate title to X location
However it doesn't appear that the Panorama has a ScrollViewer attached property.
In case you're curious, here's how I made a wide panorama item.
<controls:PanoramaItem ScrollViewer.HorizontalScrollBarVisibility="Visible" Header="movies" Orientation="Horizontal" Width="900">
<controls:PanoramaItem.HeaderTemplate >
<DataTemplate >
<StackPanel>
<TextBlock Foreground="{StaticResource PanoramaHeaderBrush}" Text="{Binding}">
</TextBlock>
</StackPanel>
</DataTemplate>
</controls:PanoramaItem.HeaderTemplate>
<StackPanel>
<!-- line list with image placeholder and text wrapping -->
<ListBox ItemsSource="{Binding Items}" >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.Template>
<ControlTemplate>
<ItemsPresenter />
</ControlTemplate>
</ListBox.Template>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="10">
<Grid Background="{StaticResource ControlTitlesInactivePivotBrush}" Width="173" Height="173" >
<TextBlock FontSize="24" Text="Movie Title (2010)" TextWrapping="Wrap" Style="{StaticResource PhoneTextGroupHeaderStyle}"/>
<Rectangle Fill="White" Height="48" Width="48" HorizontalAlignment="Right" VerticalAlignment="Bottom">
<Rectangle.OpacityMask>
<ImageBrush ImageSource="/Test;component/movie_icn.png" />
</Rectangle.OpacityMask>
</Rectangle>
</Grid>
<TextBlock Text="Movie Title:" Margin="12,0,12,0" Foreground="Black" />
<TextBlock Text="The Title" Margin="12,-6,12,0" Foreground="Gray"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</controls:PanoramaItem>
The Silverlight Panorama control doens't support the behaviour you're after or provide the ability to customize it in a way that will let you do it.
If you really want this then you'll need to build your own control from scratch. I would expect this to be more effort than is justified. Just avoid creating a very wide PanoramaItem instead.

Why does stackpanel break my pivotviewer?

I have a working pivotviewer with 128 images of cars that I put together myself. I used one of the many tutorials on the web to get it working, and it works well. Then I thought I should decorate the page a bit so I put the grid in which the pv resided inside a bounding stackpanel with a couple of textblocks above it to tell what the collection is. Everything loads fine except the images. Comment out the stackpanel lines and it works perfectly.
Any ideas? How could something so simple fail?
Here is all of the code in MainPage.xaml:
<StackPanel>
<TextBlock
FontSize="24"
HorizontalAlignment="Center"
VerticalAlignment="Top">
Silverlight Pivotviewer Example
</TextBlock>
<TextBlock
FontSize="16"
HorizontalAlignment="Center"
VerticalAlignment="top">
Cool Automobiles
</TextBlock>
<Grid x:Name="LayoutRoot" Background="White">
<pivoter:PivotViewer x:Name="pivotViewer" />
</Grid>
</StackPanel>
Your Grid, "LayoutRoot", is your main layout control. You need to wrap your StackPanel within the Grid control.
Something like this:
<Grid x:Name="LayoutRoot" Background="White"
<StackPanel>
<TextBlock
FontSize="24"
HorizontalAlignment="Center"
VerticalAlignment="Top">
Silverlight Pivotviewer Example />
<TextBlock
FontSize="16"
HorizontalAlignment="Center"
VerticalAlignment="top">
Cool Automobiles />
<pivoter:PivotViewer x:Name="pivotViewer" />
</StackPanel>
</Grid>
After your declaration of your Grid, I would add some rows, i.e. 0, 1, 2. Then I would layout your Stackpanels, PivotViewer, etc.
Hope this helps.
This is a known issue. The StackPanel is a dimensionless element. You need to add Width and Height values to the StackPanel and the PivotViewer will begin working correctly.
This is what we did. We added an event handler to the SizeChanged event on the dialog then sized the PivotViewer. Also after the Initialise or Loaded event call it too...see how you go?
void PivotDialog_SizeChanged( object sender, SizeChangedEventArgs e )
{
SizePivotViewer( );
m_PivotViewer.UpdateLayout( );
}
private void SizePivotViewer( )
{
m_PivotViewer.Width = ActualWidth;
m_PivotViewer.Height = ActualHeight - 20; // Magic number so text will display properly at bottom of Pivot!
}

Resources