在经历过HelloWorld洗礼之后,我开始尝试着做一个简单的win8.1日记本应用。然而什么东西都是想着简单,但是开始着手做的时候完全不是想的那回事。先前想好的解决方案完全用不上,先前觉得很快会过的步骤硬生生的会卡住半天,过程那叫一个痛苦啊。但是不管怎样,还是实现了一些很基本很基本的功能,而且也不是很完美,总之,且行且学习吧。
首先是界面的xaml设计,先贴上代码:
以下是登陆界面前台:一个PasswordBox控件和一个按钮
这里面最要注意两点:
1.PasswordBox控件,微软新加了这个控件,可能好多人都没适应过来,不是原先的webform的textmode="password"这种写法了
2.后台取PasswordBox控件中的数据时要用.password属性,而不是原先的.text属性了
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<PasswordBox x:Name="btnPwd" HorizontalAlignment="Left" Margin="253,202,0,0" VerticalAlignment="Top" Height="83" Width="418"/>
<Button Content="解锁" x:Name="btnLogin" FontSize="40" HorizontalAlignment="Left" Margin="880,199,0,0" VerticalAlignment="Top" Width="146" Height="89" Tapped="btnLogin_Tapped"/>
</Grid>
以下是日记本前台:
这里面的控件:
一个保存按钮,一个打开按钮,一个语音念文本的按钮
一个标题文本框,一个正文文本框
一个ListView控件,绑定后台的数据用来显示已经保存的文本的文本名称
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBox x:Name="txtTitle" HorizontalAlignment="Left" Margin="221,104,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Height="57" Width="629"/>
<TextBox x:Name="txtContent" HorizontalAlignment="Left" Margin="221,194,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="629" Height="235"/>
<Button x:Name="btnSave" Content="保存" FontSize="30" HorizontalAlignment="Left" Margin="267,493,0,0" VerticalAlignment="Top" Width="122" Height="63" Click="btnSave_Click"/>
<Button x:Name="btnOpen" Content="打开" FontSize="30" HorizontalAlignment="Left" Margin="473,493,0,0" VerticalAlignment="Top" Width="110" Height="63" Click="btnOpen_Click"/>
<Button x:Name="btnRead" Content="念出来" FontSize="30" HorizontalAlignment="Left" Margin="664,493,0,0" VerticalAlignment="Top" Width="125" Height="60" Click="btnRead_Click"/>
<ListView x:Name="list" HorizontalAlignment="Left" Height="446" Margin="885,104,0,0" VerticalAlignment="Top" Width="399">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding FileName}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<MediaElement x:Name="mediaRead" HorizontalAlignment="Left" VerticalAlignment="Top" Width="100" Height="100" />
</Grid>
其次是各自的后台处理了:
对于登陆界面而言:
注意的是PasswordBox里面数据的拾取(tbnPwd.Password)的写法
页面跳转(Frame.Navigate(typeof(MainPage)))的写法
//点击解锁按钮事件
private async void btnLogin_Tapped(object sender, TappedRoutedEventArgs e)
{
//如果PasswordBox里面的数据等于123
if (btnPwd.Password == "123")
{
//界面跳转到MainPage页面,同时传一个name参数过去
Frame.Navigate(typeof(MainPage), new { name = "美国队长"});
//同时在MainPage页面显示提示框"欢迎使用"
MessageDialog dialog = new MessageDialog("欢迎使用");
await dialog.ShowAsync();
}
else
{
//如果PasswordBox里面的数据不等于123,显示提示框"密码错误"
MessageDialog dialog = new MessageDialog("密码错误");
await dialog.ShowAsync();
}
}
对于日记页面而言:
1.最关心的问题是,前面登陆页面验证完成跳转到这个页面,日记页面对此也要做相应的处理和响应吧,再者前面还传过来一个name的参数,这个肯定是要设法取到的呀。
2.对于跳转页面的问题,在日记页面写OnNavigatedTo(...),这个方法就像是初始化(Init) ,它是在每次页面成为活动(第一次打开时)页面时调用该方法。(这个也有相对的OnNavigateFrom()方法)
3.取之前传过来的name的值,用base.OnNavigatedTo(e),dynamic obj = e.Parameter获得参数,其实可以看成是一个参数整体的对象,然后对obj进行“.”引用就可以了。(这个让我想起了用c#或者java的时候的页面传值或者超链接传值的方法,貌似分别用的是request.querystring()和request.parameter()取得数据的,我也记不清楚了)
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
dynamic obj = e.Parameter;
txtTitle.Text = "欢迎回来" + obj.name;
//遍历AppData目录,得到所有文件
StorageFolder folder = ApplicationData.Current.LocalFolder;
var fileList = await folder.GetFilesAsync();
List<FileInfo> fileInfoList = new List<FileInfo>();
foreach (var file in fileList)
{
fileInfoList.Add(new FileInfo { FileName = file.Name });
}
list.ItemsSource = fileInfoList;
}
还有就是语音问题:
关于语音这个问题,微软已经封装的很好了,几乎是不用动脑子的复制下面一段代码,然后粘贴到任何想要的位置上,改一下里面的纯文本对象就可以了。
(所以这里就带来了很多吐槽,其实c#的语言的境地开始尴尬了,很多人都说其实现在写项目用c#的话都是可以这边复制一段代码粘贴过来,那边复制一段代码粘贴过来,像搭积木一样,毫无技术可言。这一点因为微软封装的越来越好,很多东西都不需要程序员从底层调用东西了,渐渐的,很多人也都不知道自己写的具体调用了底层的哪些API。还有就是HTML5+CSS3+JS的冲击,特别是JS的越来越强大,导致c#的境地越来越窘迫。)
private async void btnRead_Click(object sender, RoutedEventArgs e)
{
// 声明控制和播放音频的Media对象.
MediaElement mediaElement = this.mediaRead;
// 声明控制语音合成引擎(声音)的对象.
var synth = new Windows.Media.SpeechSynthesis.SpeechSynthesizer();
// 从纯文本中产生音频流.
SpeechSynthesisStream stream = await synth.SynthesizeTextToStreamAsync(txtContent.Text);
// 将流发送到Media对象中.
mediaElement.SetSource(stream, stream.ContentType);
//播放文本内容语音
mediaElement.Play();
}