今天的练习是创建一个“紧急状况”的项目,涉及到的知识点有:屏幕的旋转,SIP(屏幕键盘)及处理按键时间,滚动视图,电话启动器。
1 界面设计
我们希望设计出来的界面是这样的:
当单击页面红色的标题时,拨号启动器被调用。各个文本框拥有自己的输入域,并且获得焦点的那个文本框默认全选文字。
1.1 涉及到的滚动视图问题
使用一个ScrollViewer将需要滚动的控件包裹在其中即可
1.2 输入域的问题
文本框的InputScope属性提供了11种不同类型的屏幕键盘,需要根据具体情况调用相应的键盘,通常需要实现导航到此页面自动弹出,通过处理回车事件达到额外的操作,限制输入值(需要手写代码)。
界面的代码如下所示:
<phone:PhoneApplicationPage
x:Class="IN_CASE_OF_EMERGENCY.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" d:DesignWidth="480" d:DesignHeight="768"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="PortraitOrLandscape"
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="IN CASE OF EMERGENCY" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="tab here to dial!" Margin="9,-7,0,0" FontSize="64" Foreground="Red" MouseLeftButtonUp="PageTitle_MouseLeftButtonUp"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<ScrollViewer Grid.Row="1">
<StackPanel Orientation="Vertical">
<TextBlock Text="Emergency contact people" Foreground="{StaticResource PhoneSubtleBrush}" Margin="24,5,0,2"/>
<TextBox x:Name="Ecp" InputScope="PersonalFullName" Margin="{StaticResource PhoneHorizontalMargin}" KeyDown="BoxKeyDown_Event" GotFocus="Box_GotFocus"/>
<TextBlock Text="Emergency contact people number" Foreground="{StaticResource PhoneSubtleBrush}" Margin="24,5,0,2"/>
<TextBox x:Name="Ecn" InputScope="TelephoneNumber" Margin="{StaticResource PhoneHorizontalMargin}" KeyDown="BoxKeyDown_Event" GotFocus="Box_GotFocus"/>
<TextBlock Text="Phone owner name" Foreground="{StaticResource PhoneSubtleBrush}" Margin="24,5,0,2"/>
<TextBox x:Name="Pon" InputScope="PersonalFullName" Margin="{StaticResource PhoneHorizontalMargin}" KeyDown="BoxKeyDown_Event" GotFocus="Box_GotFocus" />
<TextBlock Text="Phone owner's medical notes" Foreground="{StaticResource PhoneSubtleBrush}" Margin="24,5,0,2"/>
<TextBox x:Name="Pomn" InputScope="Text" Margin="{StaticResource PhoneHorizontalMargin}" AcceptsReturn="True" TextWrapping="Wrap" MinHeight="250" KeyDown="BoxKeyDown_Event" GotFocus="Box_GotFocus"/>
</StackPanel>
</ScrollViewer>
</Grid>
</phone:PhoneApplicationPage>
2 后端代码
2.1 实现拨号启动器的功能
private void PageTitle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
PhoneCallTask phoneLauncher = new PhoneCallTask();
phoneLauncher.DisplayName = this.Ecp.Text;
phoneLauncher.PhoneNumber = this.Ecn.Text;
//当号码不为空时,拨号
if (phoneLauncher.PhoneNumber.Length == 0)
{
MessageBox.Show("There is no emergency contact phone number to call!", "Phone", MessageBoxButton.OK);
}
else
phoneLauncher.Show();
}
效果如下图:
2.2 处理全选消息
private void Box_GotFocus(object sender, RoutedEventArgs e)
{
(sender as TextBox).SelectAll();
}
效果见下图:
2.3 实现按键消息处理
主要是实现将输入焦点进行传递的功能,要注意最后一个文本框的回车在这里面表示换行,所以我们要去掉最后一个文本框的绑定事件KeyDown。
private void BoxKeyDown_Event(object sender, KeyEventArgs e)
{
if(e.Key == Key.Enter)
{
if (sender == this.Ecp)
this.Ecn.Focus();
else if (sender == this.Ecn)
this.Pon.Focus();
else if (sender == this.Pon)
this.Pomn.Focus();
e.Handled = true;
}
}
2.4 实现独立属性设置,实现导航自动填充
使用IsolatedStorageSettings实现四个信息的保存和提取,在onNavigatingFrom和onNavigatingTo的时候更新存储,不再贴出代码。
还有个小bug就是当出现数字键盘时,没有回车键可用来转移焦点,但是对于有键盘的手机来说这不是问题。。。
另外,屏幕旋转的效果没贴出来,可以在旋转时添加相应的事件,同时还要考虑你的应用到底需不需要支持旋转,如果希望灵活一点,可以考虑添加锁定旋转的功能,后面再讨论。