问题
How do I make a scrollable form similar to that of the Phone Contact input panel in Windows Phone 8.1?
The current method of StackPanel inside a ScrollViewer restricts scrolling when the SIP launches and I have to hit back button to choose other TextBoxes.
This is not an idea UX situation and I've tried a few options of the web.
- Increasing the StackPanel's height beyond its necessary size by about 350 pixels - didn't work, as it displaces the form unevenly and doesn't return to normal
- Creating a ListBox as suggested in another site online didn't change anything either
- Increasing the down margin of the last control didn't help either
回答1:
check the below code which has worked fine for me.
Chat.xaml.cs
using System;
using System.ComponentModel;
using System.Windows.Controls;
using System.Windows.Input;
using System.Linq;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
using Microsoft.Phone.Controls;
using PhoneApplicationPage = Microsoft.Phone.Controls.PhoneApplicationPage;
namespace LIV.View
{
// ReSharper disable once RedundantExtendsListEntry
public partial class Chat : PhoneApplicationPage
{
private bool _flag;
public Chat()
{
InitializeComponent();
}
#region Static Chat Header WorkAround
public double OldHeight;
private TranslateTransform _translateTransform;
#region TranslateY dependency property
public static readonly DependencyProperty TranslateYProperty = DependencyProperty.Register(
"TranslateYProperty", typeof(double), typeof(Chat), new PropertyMetadata(default(double), PropertyChangedCallback));
private static void PropertyChangedCallback(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
var chat = o as Chat;
if (chat != null)
{
chat.UpdateTopMargin((double)e.NewValue);
}
}
public double TranslateY
{
get { return (double)GetValue(TranslateYProperty); }
set { SetValue(TranslateYProperty, value); }
}
#endregion
private void ChatPage_OnLoaded(object sender, RoutedEventArgs e)
{
var transform = ((Application.Current).RootVisual).RenderTransform as TransformGroup;
if (transform != null)
{
_translateTransform = transform.Children.OfType<TranslateTransform>().FirstOrDefault();
if (_translateTransform != null)
{
var binding = new Binding("Y")
{
Source = _translateTransform
};
BindingOperations.SetBinding(this, TranslateYProperty, binding);
}
}
}
private void UpdateTopMargin(double translateY)
{
LayoutRoot.Margin = new Thickness(0, -translateY, 0, 0);
}
#endregion
}
}
Chat.xaml
<phone:PhoneApplicationPage x:Class="LIV.View.Chat"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="Black"
Loaded="ChatPage_OnLoaded"
Orientation="Portrait"
SupportedOrientations="Portrait"
shell:SystemTray.BackgroundColor="#FF5CBFBB"
shell:SystemTray.ForegroundColor="White"
shell:SystemTray.IsVisible="True"
mc:Ignorable="d">
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Background="#FF5CBFBB">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel>
<TextBlock Foreground="White" Text="{Binding ChatUser.Name}" />
<TextBlock Foreground="White" Text="{Binding ChatTime}" />
</StackPanel>
<Button Grid.Column="1"
BorderThickness="0"
Command="{Binding TerminateCommand}"
Foreground="White">
End Chat
</Button>
</Grid>
<Grid x:Name="ContentPanel" Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListBox x:Name="MessageListBox"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ItemsSource="{Binding Messages}"
ScrollViewer.VerticalScrollBarVisibility="Visible"
Style="{StaticResource BottomListBoxStyle}">
</ListBox>
<StackPanel x:Name="MessageTextPanel"
Grid.Row="1"
Background="#FF5CBFBB">
<Grid Margin="0,0,0,-10">
<TextBlock FontSize="15" Text="{Binding UserStatus}" />
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox></TextBox>
</Grid>
</StackPanel>
</Grid>
</Grid>
</Grid>
</phone:PhoneApplicationPage>
check: ScrollViewer not scroll up while Keyboard is active
When normal

When SIP open

回答2:
How about only extending the bottom margin of the StackPanel
when the SIP is shown? IIRC there is no straightforward API to test for that, but you could use the focus state of the TextBoxes
to check when it appears or disappears.
来源:https://stackoverflow.com/questions/23064034/scrollable-form-control-in-windows-phone-8