Windows Phone开发(12):认识一下独具个性的磁贴

对“磁贴”的理解是一点也不抽象的,为什么呢?只要你愿意启动WP系统,无论你是在模拟器中还是在真机中,是的,桌面上那一块块像地板的玩意儿,就是磁贴了。
(图:磁贴)

在上图中,我们很直观地看到磁贴图块的“真”面目,呵呵,其实很明显,这个设计真的很有个性,老实说,WP刚推出的时候,很多人说它这个那个的,其实这些人只过是起起哄罢了。
我是挺喜欢桌面上那一块块的图块的,这也是WP第一次给我留下的深刻印象,毕竟在安卓和IOS上,我们看到的都是传统手机的图标显示方式,而WP总让我觉得很有个性。

好的,看完了整体的,我们来看看局部的,好吗?别小看这些正方形的图块,里面可是大有文章的哦。不信?一起去瞧瞧。

磁贴的一个图块基本上由三个元素组成——背景图,标题文字以及计数器,嗯,当然了,图块最有意思的地方,就是它有正反两面。
下图为图块正反两面的元素组成结构图。

=> 磁贴的分类。

磁贴分为应用程序磁贴和次要磁贴。
好不好理解呢?好,首先我们看看应用程序磁贴,它是指通过用户应用程序列表中长按应用程序来把应用程序固定到“开始”屏幕。

那么,如何删除呢?在“开始”屏幕上找到你要移除的图块,长按,图块左上角会出现一个小图标,我们点击这小图标即可移除该磁贴。当然了,如果你想把移动到其它位置,在此时,你只需把图标拖到对应的位置,然后在桌面上随便点一下即可完成移动操作。

次要磁贴就是相对于刚才的上面的应用程序磁贴而言的,它是由应用程序通过特定参数创建的,说直接一点嘛,就是通过我们开发者,用代码来创建的。

这个好比我们Windows桌面上的快捷方式,有的是直接指向可执行程序的,而有的是应用程序创建的,它后面带了命令行参数。举个例子吧,最典型的要数IE了,我经常上新浪微博,我希望在桌面上创建一个IE的快捷方式图标,双击运行IE的时候新打开新浪微博主页,那怎么做呢?请看下图。

这样一来,你双击快捷方式启动IE就自动打开新浪微博首页。呵呵,次要磁贴也和这相类似。

=> 动手实战。

 
下面,我们一起来动手做一个稍微综合一点的例子,嗯,现在,你可以坐下来,先喝几口奶茶,然后启动VS,新建一个WP项目。
界面布局大致如下,你可以自由发挥。

准备好两张美图,图片内容你喜欢,但要键康哦,尺寸为173*173像素,.jpg或.png都行,一张作为磁贴的正面背景,另一张作为磁贴的背面背景。
注意:把图片的生成操作改为“内容”。

当然,为了方便大家练习参考,我把XAML贴出来,希望大家不要直接复制,而是认认真真的在VS里面输一遍,要多写代码多练习才会找到感觉的哦。

  1. <phone:PhoneApplicationPage
  2. x:Class="ShellTitleApp.MainPage"
  3. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  4. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  5. xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
  6. xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
  7. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  8. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  9. mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
  10. FontFamily="{StaticResource PhoneFontFamilyNormal}"
  11. FontSize="{StaticResource PhoneFontSizeNormal}"
  12. Foreground="{StaticResource PhoneForegroundBrush}"
  13. SupportedOrientations="Portrait" Orientation="Portrait"
  14. shell:SystemTray.IsVisible="True">
  15. <phone:PhoneApplicationPage.Resources>
  16. <Style x:Key="textblStyle" TargetType="TextBlock">
  17. <Setter Property="FontSize" Value="28"/>
  18. <Setter Property="Margin" Value="0,12,5,6"/>
  19. <Setter Property="HorizontalAlignment" Value="Right"/>
  20. </Style>
  21. <Style x:Key="textboxStyle" TargetType="TextBox">
  22. <Setter Property="FontSize" Value="28"/>
  23. <Setter Property="Width" Value="300"/>
  24. <Setter Property="Height" Value="auto"/>
  25. <Setter Property="HorizontalAlignment" Value="Left"/>
  26. </Style>
  27. </phone:PhoneApplicationPage.Resources>
  28. <!--LayoutRoot 是包含所有页面内容的根网格-->
  29. <Grid x:Name="LayoutRoot" Background="Transparent">
  30. <Grid.RowDefinitions>
  31. <RowDefinition Height="Auto"/>
  32. <RowDefinition Height="*"/>
  33. </Grid.RowDefinitions>
  34. <!--TitlePanel 包含应用程序的名称和页标题-->
  35. <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
  36. <TextBlock x:Name="ApplicationTitle" Text="我的应用程序" Style="{StaticResource PhoneTextNormalStyle}"/>
  37. <TextBlock x:Name="PageTitle" Text="示例程序" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
  38. </StackPanel>
  39. <!--ContentPanel - 在此处放置其他内容-->
  40. <Grid x:Name="ContentPanel" Margin="0" Grid.Row="1">
  41. <Grid.RowDefinitions>
  42. <RowDefinition Height="*" />
  43. <RowDefinition Height="auto" />
  44. </Grid.RowDefinitions>
  45. <ScrollViewer HorizontalScrollBarVisibility="Auto" Grid.Row="0">
  46. <Grid Margin="1">
  47. <Grid.RowDefinitions>
  48. <RowDefinition Height="auto"/>
  49. <RowDefinition Height="auto"/>
  50. <RowDefinition Height="auto"/>
  51. <RowDefinition Height="auto"/>
  52. <RowDefinition Height="auto"/>
  53. </Grid.RowDefinitions>
  54. <Grid.ColumnDefinitions>
  55. <ColumnDefinition Width="auto"/>
  56. <ColumnDefinition Width="*"/>
  57. </Grid.ColumnDefinitions>
  58. <TextBlock Grid.Row="0"
  59. Grid.Column="0"
  60. Text="正面标题:" Style="{StaticResource textblStyle}" />
  61. <TextBox x:Name="txtForeTitle"
  62. Style="{StaticResource textboxStyle}"
  63. Grid.Row="0"
  64. Grid.Column="1"/>
  65. <TextBlock Text="计数器:" Style="{StaticResource textblStyle}"
  66. Grid.Row="1"
  67. Grid.Column="0"/>
  68. <TextBox x:Name="txtCount"
  69. Grid.Column="1"
  70. Grid.Row="1" Style="{StaticResource textboxStyle}" >
  71. <!--只允许输入数字-->
  72. <TextBox.InputScope>
  73. <InputScope >
  74. <InputScopeName NameValue="Number"/>
  75. </InputScope>
  76. </TextBox.InputScope>
  77. </TextBox>
  78. <TextBlock Text="背面标题:"
  79. Grid.Row="2"
  80. Grid.Column="0" Style="{StaticResource textblStyle}" />
  81. <TextBox x:Name="txtBackTitle"
  82. Grid.Row="2"
  83. Grid.Column="1" Style="{StaticResource textboxStyle}" />
  84. <TextBlock Text="背景内容:"
  85. Grid.Row="3"
  86. Grid.Column="0" Style="{StaticResource textblStyle}" />
  87. <TextBox x:Name="txtBackContent"
  88. Grid.Row="3"
  89. Grid.Column="1" Style="{StaticResource textboxStyle}" />
  90. <!--提示是以何种方式启动-->
  91. <CheckBox x:Name="chkStartType"
  92. IsChecked="False"
  93. Grid.Row="4"
  94. Grid.Column="0"
  95. Grid.ColumnSpan="2"
  96. FontSize="30"
  97. Content="通过应用程序创建的磁贴启动" IsEnabled="False" />
  98. </Grid>
  99. </ScrollViewer>
  100. <StackPanel Grid.Row="1" Orientation="Horizontal">
  101. <Button x:Name="btnAddToShellTitle"
  102. Content="添加磁贴" Click="btnAddToShellTitle_Click" />
  103. <Button x:Name="btnUpdateShellTitle"
  104. Content="更新" Click="btnUpdateShellTitle_Click" />
  105. <Button x:Name="btnDeleteShellTitle"
  106. Content="删除" Click="btnDeleteShellTitle_Click" />
  107. </StackPanel>
  108. </Grid>
  109. </Grid>
  110. </phone:PhoneApplicationPage>

好的,最后,当然是把C#代码也写完。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Net;
  5. using System.Windows;
  6. using System.Windows.Controls;
  7. using System.Windows.Documents;
  8. using System.Windows.Input;
  9. using System.Windows.Media;
  10. using System.Windows.Media.Animation;
  11. using System.Windows.Shapes;
  12. using Microsoft.Phone.Controls;
  13. using Microsoft.Phone.Shell;
  14. using System.Windows.Threading;
  15. namespace ShellTitleApp
  16. {
  17. public partial class MainPage : PhoneApplicationPage
  18. {
  19. // 要用的图片的相对路径
  20. private const string FORE_PIC = "images/a.png";
  21. private const string BACK_PIC = "images/b.png";
  22. // 构造函数
  23. public MainPage()
  24. {
  25. InitializeComponent();
  26. }
  27. protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
  28. {
  29. base.OnNavigatedTo(e);
  30. // 创建的磁贴的启动地址其实是指向 /MainPage.xaml?s=1
  31. // s=1参数是为了区别用户是不是通过程序所创建的磁贴来进入启动当前程序的,
  32. // 就像面前例子中讲到的把IE桌面快捷方式的参数指定为新浪微博的主页一个道理。
  33. // 检测是否存在s=1来判断是否通过程序创建的磁贴来启动。
  34. ShellTile myTitle = ShellTile.ActiveTiles.FirstOrDefault(n => n.NavigationUri.ToString().Contains("s=1"));
  35. if (myTitle != null)
  36. {
  37. this.chkStartType.IsChecked = true;
  38. }
  39. else
  40. {
  41. this.chkStartType.IsChecked = false;
  42. }
  43. }
  44. // 创建图块
  45. private void btnAddToShellTitle_Click(object sender, RoutedEventArgs e)
  46. {
  47. // 不管我们的程序是否创建“开始”屏幕磁贴,ActiveTiles的第一个元素必是当前正在前台运行的
  48. // 应用程序。所以,在取出第一个ShellTile时,一定要通过判断是否存在s=1。
  49. // 这个s=1参数是随便取的。
  50. ShellTile myTitle = ShellTile.ActiveTiles.FirstOrDefault(m => m.NavigationUri.ToString().Contains("s=1"));
  51. // 如果已经创建就不建了。
  52. if (myTitle != null)
  53. {
  54. MessageBox.Show("此应用程序的磁贴已经存在。");
  55. }
  56. else
  57. {
  58. // 创建新磁贴
  59. int Counter = 0;
  60. // StandardTileData就是用来传递ShellTitle的属性参数的,
  61. // 如正面背景图的URI,标题,计数器等。
  62. StandardTileData myData = new StandardTileData()
  63. {
  64. Title = string.IsNullOrEmpty(txtForeTitle.Text) == true ? string.Empty : txtForeTitle.Text,
  65. Count = int.TryParse(txtCount.Text, out Counter) == true ? Counter : 0,
  66. BackTitle = string.IsNullOrEmpty(txtBackTitle.Text) == true ? string.Empty : txtBackTitle.Text,
  67. BackContent = string.IsNullOrEmpty(txtBackContent.Text) == true ? string.Empty : txtBackContent.Text,
  68. BackgroundImage = new Uri(FORE_PIC, UriKind.Relative),
  69. BackBackgroundImage = new Uri(BACK_PIC, UriKind.Relative)
  70. };
  71. // ShellTile.Create方法的第一个参数是我们启动应用程序时应该导航到哪里。
  72. // 因为本示例主有一个页面,当然是导航到主页面,
  73. // 因为是从我们创建的磁贴来启动的,所以不要忘了带上s=1参数。
  74. ShellTile.Create(new Uri("/MainPage.xaml?s=1", UriKind.Relative), myData);
  75. MessageBox.Show("磁贴图块创建成功。");
  76. }
  77. }
  78. // 更新磁贴信息
  79. private void btnUpdateShellTitle_Click(object sender, RoutedEventArgs e)
  80. {
  81. // 同理,先要判断是否从我们创建的磁贴启动
  82. ShellTile myTitle = ShellTile.ActiveTiles.FirstOrDefault(m => m.NavigationUri.ToString().Contains("s=1"));
  83. if (myTitle != null)
  84. {
  85. int Counter = 0;
  86. StandardTileData data = new StandardTileData();
  87. if (!string.IsNullOrEmpty(txtForeTitle.Text))
  88. {
  89. data.Title = txtForeTitle.Text;
  90. }
  91. if (int.TryParse(txtCount.Text,out Counter))
  92. {
  93. data.Count = Counter;
  94. }
  95. if (!string.IsNullOrEmpty(txtBackTitle.Text))
  96. {
  97. data.BackTitle = txtBackTitle.Text;
  98. }
  99. if (!string.IsNullOrEmpty(txtBackContent.Text))
  100. {
  101. data.BackContent = txtBackContent.Text;
  102. }
  103. myTitle.Update(data);
  104. MessageBox.Show("磁贴数据更新完成。");
  105. }
  106. }
  107. // 删除磁贴
  108. // 注意:我们使用代码只可删除次要磁贴,也就是我们用代码创建的,
  109. // 不要去删除应用程序磁贴,即通过在应用程序项上长按创建的。
  110. private void btnDeleteShellTitle_Click(object sender, RoutedEventArgs e)
  111. {
  112. // 记着,要先判断是否找到通过我们代码创建的磁贴。
  113. ShellTile title = ShellTile.ActiveTiles.FirstOrDefault(x => x.NavigationUri.ToString().Contains("s=1"));
  114. if (title != null)
  115. {
  116. title.Delete();
  117. MessageBox.Show("磁贴图块删除成功。");
  118. }
  119. }
  120. }
  121. }

示例中我们重点是使用了ShellTile类,它并不复杂,成员不多,大家多玩几次就熟了。

运行之后,我们在“开始”屏幕中创建我们的磁贴,然后回到桌面,我们盯着它别动,你会发现,它的正面与反面会每隔几秒钟自动轮回切换。

时间: 2024-10-16 15:29:15

Windows Phone开发(12):认识一下独具个性的磁贴的相关文章

Windows Phone开发(12):认识一下独具个性的磁贴(转)

对"磁贴"的理解是一点也不抽象的,为什么呢?只要你愿意启动WP系统,无论你是在模拟器中还是在真机中,是的,桌面上那一块块像地板的玩意儿,就是磁贴了.(图:磁贴) 在上图中,我们很直观地看到磁贴图块的"真"面目,呵呵,其实很明显,这个设计真的很有个性,老实说,WP刚推出的时候,很多人说它这个那个的,其实这些人只过是起起哄罢了.我是挺喜欢桌面上那一块块的图块的,这也是WP第一次给我留下的深刻印象,毕竟在安卓和IOS上,我们看到的都是传统手机的图标显示方式,而WP总让我觉

【万里征程——Windows App开发】应用设置和应用帮助

"设置"合约 上一节中我们学习了如何将应用设置保存到本地,这种方式是通过在App内添加设置选项,这里还有一种方式.微软将其称为"设置"合约,并且所有的Windows应用商店应用都将自动配合这种合约.但是应用自带的这种设置如果不做任何修改可谓毫无作用.而我们添加这些设置则可以让应用更加个性化哦. SettingsFlyout 首先新建一个SettingsFlyout页面,也许很多童鞋会像我当初学这个一样立马就调试程序等着看看这个设置是长什么样,不过现在还用不了哦. 如

Windows App开发之文件与数据

读取文件和目录名 这一节開始我们将陆续看到Windows App是如何操作文件的. 在Windows上读取文件名称.目录名 首先我们在XAML中定义一个Button和TextBlock,将读取文件/目录名的过程写在前者的click事件中.后者则用来显示文件信息. <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <StackPanel Orientation="Ho

【万里征程——Windows App开发】SemanticZoom视图切换

相信用过Windows Phone或者Windows 8/8.1/10的朋友对下面这张截图肯定不陌生.这就是通过SemanticZoom来实现的,当数据过多时,这种控件尤其适用.它有一个放大视图ZoomedInView和一个缩小试图ZoomedOutView,前者主要用来显示当前页面的详细信息,后者则致力于快速导航. 那么我就自己来动手实践咯,首先我们在XAML中添加大致的界面,就像画画要先画轮廓一样. <Grid Name="grid1" Background="{T

【万里征程——Windows App开发】如何保存、读取、删除应用数据

在前面的几篇博客中,都是关于数据的,这方面的内容其实还有很多很多,省略掉一部分后,也还是有很多.这一篇将是很重要的一部分,关于保存和读取数据,对于游戏而言,这一点尤其重要. 先来看看一个大概的背景吧,我这里写的很简单啦^_^ 保存的内容就是这四个框框里填写的数据咯.先上XAML代码. <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <StackPanel Orientati

【万里征程——Windows App开发】ListView&amp;GridView之分组

本文承接[万里征程--Windows App开发]ListView&GridView之添加数据. 在上一篇中我们已经了解了怎样将数据绑定到ListView或GridView,但既然要用到这两个控件往往是因为数据繁多,那么几乎就不可避免的要让其能够分组.我们所绑定的数据源可能是项列表,其中的每个项甚至还有其自己的项,那么问题就来了. 一时不会也想不出什么宏伟的例子,就做一个简单的闹钟的时间表的ListView和GridView吧.那么先在项目中添加一个类,最好在Shared下.内容都是很简易的,闹

【万里征程——Windows App开发】设置共享(共享源和共享目标)

上一篇博客简单介绍了通过粘贴板来共享数据,这一节将会添加更为强大的功能哦. 以下就是大概的样式了,随便看看就好了,这都不是重点. <Grid Background="AliceBlue"> <Grid.RowDefinitions> <RowDefinition Height="auto"/> <RowDefinition /> <RowDefinition Height="auto"/>

Redis的Windows端开发连接Linux端以及相应的代码实现

在Windows端开发连接需要进行配置文件的配置: 在redis.conf配置文件中 将protected-mode yes,修改为protected-mode no:不保护redis # By default protected mode is enabled. You should disable it only if # you are sure you want clients from other hosts to connect to Redis # even if no authe

Windows驱动开发基础(八)内存管理

Windows驱动开发基础系列,转载请标明出处:http://blog.csdn.net/ikerpeng/article/details/38826159 就32位的计算机来说,他有4G的真实的物理内存.但是这样是不够的,于是引入了虚拟内存的概念.使得每一个进程都有4G的虚拟内存. 虚拟内存实际上就是采用了一种映射的方式.4G的内存实际上被分页.一般来说一个页的大小是4K.也是说它被分为了1M个页.在这么多的页里面,有一部分是对应于物理内存的(可以是多对一的):有一部分是对应于磁盘上的空间,但