Reputation: 129
I have a screen which consists of several UI elements, mainly TextBoxes. When a TextBox gets focused whole page pushes up, moving the header outside the screen. I want the header to be at fixed position and the rest of the content to be pushed up inside a ScrollViewer. Ideally, I would like the offsets to be placed as intended and show/hide keyboard with correct focusing to the UI element. A good example to the correct scrolling behaviour is native Alarm app. Any help is appreciated. Cheers!
Upvotes: 3
Views: 619
Reputation: 6178
When SIP keyboard is rendered, PhoneApplicationFrame.TranslateTransform.Y is set to specific values. To update layout, we’ll just set top margin to the specified value(-s) and after that Silverlight layout system will fix the issue.
here XAML part:
<Grid x:Name="LayoutRoot" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="WINDOWS PHONE" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Text="developer's ?" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<Grid Grid.Row="1" Margin="12,0,12,0"></Grid>
<TextBox Grid.Row="2" LostFocus="TextBox_OnLostFocus" />
</Grid>
C# portions
public partial class MainPage : PhoneApplicationPage
{
private static double newValue = 0.0;
public static readonly DependencyProperty TranslateYProperty = DependencyProperty.Register("TranslateY", typeof(double), typeof(MainPage), new PropertyMetadata(0d, OnRenderXPropertyChanged));
public MainPage()
{
InitializeComponent();
this.Loaded += BindToKeyboardFocus;
}
private void BindToKeyboardFocus(object sender, RoutedEventArgs e)
{
PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
if (frame != null)
{
var group = frame.RenderTransform as TransformGroup;
if (group != null)
{
var translate = group.Children[0] as TranslateTransform;
var translateYBinding = new Binding("Y");
translateYBinding.Source = translate;
SetBinding(TranslateYProperty, translateYBinding);
}
}
}
public double TranslateY
{
get { return (double)GetValue(TranslateYProperty); }
set { SetValue(TranslateYProperty, value); }
}
private static void OnRenderXPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if ((double)e.NewValue <= newValue)
((MainPage)d).UpdateTopMargin((double)e.NewValue);
newValue = (double)e.NewValue;
}
private void UpdateTopMargin(double translateY)
{
LayoutRoot.Margin = new Thickness(0, -translateY, 0, 0);
}
private void TextBox_OnLostFocus(object sender, RoutedEventArgs e)
{
LayoutRoot.Margin = new Thickness();
}
}
I think it will be helpful. Here is my GitHub link- https://github.com/rezacse/fixedHeaderOnTextBoxFocus
Upvotes: 1
Reputation: 3162
I had the same issue. but at last i solved it, i just used the Height property to do this. Please do the following steps
See the below Code
<ScrollViewer Height="500">
<Grid Name="Container" Height="700">
<TextBox/>
<TextBox/>
<TextBox/>
</Grid>
</ScrollViewer>
Now you can scroll the container Grid Even the KeyBoard shown or even focus on a TextBox. you can focus any text box and the ScrollViewer 'll not scroll back.
Upvotes: 0