Problem:
Generally in windows phone when TextBox is focus soft-keyboard will be open ,but here problem is by default page screen to shift upwards when keyboard opened and again shift previous position when user closed the keyboard by tap on screen.Actually this question is raised at MSDN WindowsPhone Development Forums.Even lot of times this question is raised by developers and however more resource's available for solving this issue.
Requirement :Page UI having header,body and footer. In page UI there is a TextBox just above the footer. When user focus on this TextBox the page header is going to invisible.But user doesn't want to page header shift upwards when keyboard is opened
Note: This Sample is targeted on WindowsPhone 7.1
SourceFile at:WpKeyBoardIssueSample
Solution:
Step1: Take Grid layout with 3 rows for Header,Body,Footer.
Note: Please share your thoughts,what you think about this post,Is this post really helpful for you?otherwise it would be very happy ,if you have any thoughts for to implement this requirement in any another way?I always welcome if you drop comments on this post and it would be impressive.
Generally in windows phone when TextBox is focus soft-keyboard will be open ,but here problem is by default page screen to shift upwards when keyboard opened and again shift previous position when user closed the keyboard by tap on screen.Actually this question is raised at MSDN WindowsPhone Development Forums.Even lot of times this question is raised by developers and however more resource's available for solving this issue.
Requirement :Page UI having header,body and footer. In page UI there is a TextBox just above the footer. When user focus on this TextBox the page header is going to invisible.But user doesn't want to page header shift upwards when keyboard is opened
Note: This Sample is targeted on WindowsPhone 7.1
SourceFile at:WpKeyBoardIssueSample
Solution:
Step1: Take Grid layout with 3 rows for Header,Body,Footer.
XAML
<Grid x:Name="LayoutRoot" Grid.Row="1" Margin="12,0,12,0">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Name="Header" Background="#FF1DA8D1">
<TextBlock Text="Header" HorizontalAlignment="Center" FontSize="40" />
</StackPanel>
<ScrollViewer Grid.Row="1" Background="Orange" Name="Body">
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Name="txtMessage"
TextWrapping="Wrap"
AcceptsReturn="True"
TextChanged="txtMessage_TextChanged"
GotFocus="txtMessage_GotFocus"
LostFocus="txtMessage_LostFocus"
Tap="txtMessage_Tap" />
<TextBox VerticalAlignment="Bottom" Grid.Row="1" Name="txtMessage1"
TextWrapping="Wrap"
AcceptsReturn="True"
TextChanged="txtMessage_TextChanged"
GotFocus="txtMessage_GotFocus"
LostFocus="txtMessage_LostFocus"
Tap="txtMessage_Tap" />
<TextBox Grid.Row="2"
TextWrapping="Wrap"
AcceptsReturn="True"
TextChanged="txtMessage_TextChanged"
GotFocus="txtMessage_GotFocus"
LostFocus="txtMessage_LostFocus"
Tap="txtMessage_Tap" />
<TextBox VerticalAlignment="Bottom" Grid.Row="3"
TextWrapping="Wrap"
AcceptsReturn="True"
TextChanged="txtMessage_TextChanged"
GotFocus="txtMessage_GotFocus"
LostFocus="txtMessage_LostFocus"
Tap="txtMessage_Tap" />
<TextBox Grid.Row="4"
TextWrapping="Wrap"
AcceptsReturn="True"
TextChanged="txtMessage_TextChanged"
GotFocus="txtMessage_GotFocus"
LostFocus="txtMessage_LostFocus"
Tap="txtMessage_Tap" />
<TextBox VerticalAlignment="Bottom" Grid.Row="5"
TextWrapping="Wrap"
AcceptsReturn="True"
TextChanged="txtMessage_TextChanged"
GotFocus="txtMessage_GotFocus"
LostFocus="txtMessage_LostFocus"
Tap="txtMessage_Tap" />
<TextBox Grid.Row="6"
TextWrapping="Wrap"
AcceptsReturn="True"
TextChanged="txtMessage_TextChanged"
GotFocus="txtMessage_GotFocus"
LostFocus="txtMessage_LostFocus"
Tap="txtMessage_Tap" />
<TextBox VerticalAlignment="Bottom" Grid.Row="7"
TextWrapping="Wrap"
AcceptsReturn="True"
TextChanged="txtMessage_TextChanged"
GotFocus="txtMessage_GotFocus"
LostFocus="txtMessage_LostFocus"
Tap="txtMessage_Tap" />
<StackPanel Visibility="Collapsed" Name="footerkeyboard"
VerticalAlignment="Bottom" Grid.Row="8" Background="#FF1DA8D1">
<TextBlock Text="Footer" HorizontalAlignment="Center" FontSize="40" />
</StackPanel>
</Grid>
</ScrollViewer>
<!--mimic the keyboard taking up space-->
<Grid Grid.Row="2" Name="FooterPlaceholder" Visibility="Collapsed"/>
<StackPanel Name="withoutkeyboardfooter" Grid.Row="2" Background="#FF1DA8D1">
<TextBlock Text="Footer" HorizontalAlignment="Center" FontSize="40" />
</StackPanel>
<Grid>
Step2: In Above xaml code main part is Body(Grid.Row=1) content which is having scrollviewer with eight TextBox's for testing purpose.So that here every TextBox is having following events to handle keyboard issue.- TextChanged="txtMessage_TextChanged"
- GotFocus="txtMessage_GotFocus"
- LostFocus="txtMessage_LostFocus"
- Tap="txtMessage_Tap"
Here we need to use these events for manually specifying the scroll positions.Generally on initially tapping a populated Textbox, scrolling to the point at which the user wants the cursor to be specifically to an area that would be hidden after the keyboard is shown requires some manual means to accomplish. This is handled on the Tap event.
Step3: In Above xaml code another main part is (Grid.Row=2) content which is having Grid(FooterPlaceholder) & StackPanel(withoutkeyboardfooter) .Actually this row content is only for (Footer) which is mimic the keyboard taking up space.
Output Screens:
C#
double tapOffset;
private void txtMessage_Tap(object sender, System.Windows.Input.
GestureEventArgs e)
{
tapOffset = e.GetPosition(txtMessage).Y - 80;
}
When typing multiple line textbox by default entered page will be upwards,so fix this, keep resetting theApplicationRootFrame’s RenderTransformation property whenever the TextBox gets Focus.
C#
private void txtMessage_GotFocus(object sender, RoutedEventArgs e)
{
((App)Application.Current).RootFrame.RenderTransform =
new CompositeTransform();
FooterPlaceholder.Visibility = Visibility.Visible;
withoutkeyboardfooter.Visibility = Visibility.Collapsed;
footerkeyboard.Visibility = Visibility.Visible;
}
Note: The keyboard height differs between different resolutions, so some checking is required to find the correct keyboard height, which can be done on the page’s Loaded event.
C#
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
var deviceWidth = this.ActualWidth;
var isHdDevice = (deviceWidth > 500 ? true : false);
if (isHdDevice)
keyboardHeight = 540;
else
keyboardHeight = 336;
//this will be used to offset other controls on the page into the viewable area
FooterPlaceholder.Height = keyboardHeight;
}
In our UI,every textbox is having properties like TextWrapping="Wrap" & AcceptsReturn="True".This is required to so that as text wraps down to new lines the caret is kept in view. We do this by manually scrolling the ScrollViewer as the TextBox size increases. This is done in the TextChangedevent of the TextBox.
C#
private void txtMessage_TextChanged(object sender, TextChangedEventArgs e)
{
Dispatcher.BeginInvoke(() =>
{
double CurrentInputHeight = txtMessage.ActualHeight;
//after the user starts typing text, text will eventually wrap to the next line
//this ensures the textbox height doesnt sink below the bottom of the scrollviewer
if (CurrentInputHeight > InputHeight)
{
Body.ScrollToVerticalOffset(Body.VerticalOffset + CurrentInputHeight - InputHeight);
}
InputHeight = CurrentInputHeight;
});
}
And we need to do like this at LostFocus Event
C#
private void txtMessage_LostFocus(object sender, RoutedEventArgs e)
{
//hide the keyboard placeholder from screen
//allowing the scrollviewer to re-occupy the available area again
this.FooterPlaceholder.Visibility = Visibility.Collapsed;
withoutkeyboardfooter.Visibility = Visibility.Visible;
footerkeyboard.Visibility = Visibility.Collapsed;
}
Step3: In Above xaml code another main part is (Grid.Row=2) content which is having Grid(FooterPlaceholder) & StackPanel(withoutkeyboardfooter) .Actually this row content is only for (Footer) which is mimic the keyboard taking up space.
- Create a FooterPlaceholder UI element that simulates the space the keyboard takes up on the page, which effectively squishes the ScrollViewer into the available space.
- Only display when the TextBox gets focus (i.e. only the keyboard is visible) and hide it when it doesn’t, using the GotFocus and LostFocus events.
- Note the keyboard height differs between different resolutions, so some checking is required to find the correct keyboard height, which can be done on the page’s Loaded event.
Note: Please share your thoughts,what you think about this post,Is this post really helpful for you?otherwise it would be very happy ,if you have any thoughts for to implement this requirement in any another way?I always welcome if you drop comments on this post and it would be impressive.
C#
void
C#
private void txtMessage_TextChanged(object sender, TextChangedEventArgs e)
{
Dispatcher.BeginInvoke(() =>
{
Great share! But there is one problem, similar solution doesn't work for landscape mode :|. Can you please guide me in achieving similar soln. for landscape mode?
ReplyDeleteHi I am using flipview Control(UWP) and want to stop flip of records in mobile over touch not want to disable. Do you have any exposer on it.
ReplyDelete