本来按顺序应该轮到那个直尺的应用了,但是昨晚实在是忙活了半天还是没搞出来,留着继续研究研究。。。今天开始的应用算是到目前为止实用技术最多的一个。
涉及到的知识点有:
- Data Binding
- Data Template
- 列表控件(ListBox)
- 页面导航
1 主页面界面设计
<!--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="BABY SIGN LANGUAGE" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="home" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ListBox x:Name="ItemListBox" SelectionChanged="ItemListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" Margin="{StaticResource PhoneMargin}" Style="{StaticResource PhoneTextExtraLargeStyle}" Foreground="{StaticResource PhoneAccentBrush}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>
<!--Sample code showing usage of ApplicationBar-->
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
<shell:ApplicationBar.MenuItems>
<shell:ApplicationBarMenuItem Text="About" Click="ApplicationBarMenuItem_Click"/>
</shell:ApplicationBar.MenuItems>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
需要说明的是ListBox中间的代码块,使用了DataTemplate定制ListBox的每一项的表现形式,以及使用了TextBlock进行数据绑定,使得当后台数据发生变化时能自动更新UI。(Binding + 属性名称时这个属性名称是不会在Intelli作用下显示的,所以千万不要以为哪里出错了!)
int catagoryIndex = -1;
public MainPage()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
if (this.ItemListBox.Items.Count > 0)
return;
if (this.catagoryIndex == -1)
{
foreach (Catagory catagory in Data.Catagories)
this.ItemListBox.Items.Add(catagory);
}
else
{
foreach (Sign sign in Data.Catagories[this.catagoryIndex].Sign)
this.ItemListBox.Items.Add(sign);
}
}
效果是这样的:
2 主要逻辑实现
2.1 about页面跳转及about页面的设计
先来最简单的一个,需要实现当点击底部菜单栏的about菜单时,页面跳转到显示程序信息的页面,显示信息包含引用程序名称,版本号,描述以及应用图标。
private void ApplicationBarMenuItem_Click(object sender, EventArgs e)
{
this.NavigationService.Navigate(new Uri("/Share/About.xaml?appName=Baby Sign Language", UriKind.Relative));
}
实现了跳转到页面About.xaml的功能,同时还添加了查询字符串appName(注意这里等号前不能有空格的),便于About页面获取应用程序名称。
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border x:Name="ImageBorder" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center">
<Image Source="/Background.png" Stretch="None"/>
</Border>
<TextBlock x:Name="AppName" Grid.Row="1" TextAlignment="Center" VerticalAlignment="Bottom" Text="充个数先" Foreground="{StaticResource PhoneSubtleBrush}" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock x:Name="VersionNum" Grid.Row="2" TextAlignment="Center" VerticalAlignment="Top" Text="我也是来充数的" Foreground="{StaticResource PhoneSubtleBrush}" Style="{StaticResource PhoneTextExtraLargeStyle}" />
<TextBlock x:Name="Description" Grid.Row="3" TextWrapping="Wrap" Text="This is an app for baby,,,,,ae well as for adult,,,In fact ,I don't know either!" Foreground="{StaticResource PhoneSubtleBrush}"/>
</Grid>
在代码中实现应用程序名称和版本号的获取
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (this.NavigationContext.QueryString.ContainsKey("appName"))
{
this.AppName.Text = this.NavigationContext.QueryString["appName"].ToUpperInvariant();
}
//下面这句话是没有权限调用的,会出错
//string s = typeof(About).Assembly.GetName().Version.ToString();
string s = typeof(About).Assembly.ToString();
if (s != null && s.IndexOf("Version=") >= 0)
{
s = s.Substring(s.IndexOf("Version=") + "version=".Length);
s = s.Substring(0, s.IndexOf(","));
this.VersionNum.Text = "version" + s;
}
}
至此我们的About页面也做好了,下面开始做主页面列表选项的点击更新页面的操作。
2.2 列表选项响应
private void ItemListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (this.ItemListBox.SelectedIndex == -1)
return;
if (this.catagoryIndex == -1)
this.NavigationService.Navigate(new Uri("/MainPage.xaml?catagoryIndex=" + this.ItemListBox.SelectedIndex, UriKind.Relative));
else
{
this.NavigationService.Navigate(new Uri("/MainPage.xaml?catagoryIndex=" + this.catagoryIndex + "&signIndex=" + this.ItemListBox.SelectedIndex, UriKind.Relative));
}
this.ItemListBox.SelectedIndex = -1;
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (this.NavigationContext.QueryString.ContainsKey("catagoryIndex"))
{
this.catagoryIndex = int.Parse(this.NavigationContext.QueryString["catagoryIndex"]);
this.PageTitle.Text = Data.Catagories[this.catagoryIndex].Name;
}
}
2.3 二级子页面,显示图片及说明
<!--ContentPanel - place additional content here-->
<ScrollViewer Grid.Row="1">
<StackPanel Orientation="Vertical" Margin="{StaticResource PhoneHorizontalMargin}">
<Image x:Name="ItemImage"/>
<TextBlock x:Name="ItemtextBlock" Margin="{StaticResource PhoneMargin}" TextWrapping="Wrap"/>
</StackPanel>
</ScrollViewer>
以及后端业务实现
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (!this.NavigationContext.QueryString.ContainsKey("catagoryIndex") && !this.NavigationContext.QueryString.ContainsKey("signIndex"))
return;
else
{
int catagoryIndex = int.Parse(this.NavigationContext.QueryString["catagoryIndex"]);
int signIndex = int.Parse(this.NavigationContext.QueryString["signIndex"]);
Sign sign = Data.Catagories[catagoryIndex].Sign[signIndex];
this.PageTitle.Text = this.PageTitle.Text = Data.Catagories[catagoryIndex].Sign[signIndex].Name;
this.ItemImage.Source = new BitmapImage(sign.ImageUri);
this.ItemtextBlock.Text = sign.Description;
}
}
效果是这样的:
总结起来,本练习最重要的部分是页面的跳转及页面间通过Uri传值和获取的方法,为ListBox添加数据模板和数据绑定的功能,还需要看看书掌握一下。