设为首页 收藏本站
查看: 1195|回复: 0

[经验分享] 《C#高级编程(第8版)》之用C# 2012和.NET 4.5编写Windows 8样式应用程序技巧

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-11-4 09:11:35 | 显示全部楼层 |阅读模式
  
  本文介绍Windows 8应用程序的设计原则和WPF不支持的一些特殊XAML功能,演示操作Windows 8应用程序的几个方面,例如响应布局的变化,使用Windows Runtime存储API和文件选择器读写文件,使用协议与其他应用程序通信等。 DSC0000.jpg



一  Windows 8的现代UI设计

      Windows 8应用程序中第一个引人注目的地方是,它们看起来与桌面应用程序不同。UI设计着重强调了一点,就是用户在使用应用程序时应感到愉悦和享受。Windows 8应用程序如此注重设计,源自一些旧有的理念。其中一个理念是瑞士风格的图形设计,这是20世纪50年代提出的,强调干净(不凌乱)和易于理解。例如,飞机场和火车站的信号就基于这个概念,用户可以尽快处理信息。

     德国著名的包浩斯(Bauhaus)学校是现代UI设计的另一个发源地,它在1919年—1933年间极有影响力。这所学院的目标是将艺术、工艺和技术结合起来,根据功能而不是装饰来设计—— 没有任何多余的修饰。

第三个基础是电影艺术定义的动作。动画是给应用程序带来生气的重要工具,Windows 8框架提供了丰富的动画功能,使用户在传递信息时具有身历其境的体验,把使用应用程序变成一种享受。

1.1  内容,不是chrome设计

      设计Windows 8应用程序的指导原则是注重内容,这意味着,在任何时刻,都只向用户显示他们需要的信息,而不是用他们不需要的信息(即chrome,如菜单、工具栏等)。用户打开Internet Explorer时,内容就会占满整个视图。菜单是隐藏的,除非用户显式激活了它。

例如,网页占满了整个屏幕,用户可以快速搜寻需要的内容,而没有各种菜单和工具栏的打扰。图1显示了一个天气应用程序的主视图。注意大图形更便于用户迅速把注意力集中在需要的信息上。


  
  
  

DSC0001.jpg

图1
      当然,在应用程序内,用户也可以改变设置,使用命令。要修改设置,可以使用新的Charms工具栏(Charms bar)。要激活Charms工具栏,用户可以单击屏幕的右边界,调用改变应用程序设置所需的控件。

命令放在屏幕顶部或底部的app工具栏中,要激活这些命令,用户可以使用类似的方式,即单击屏幕的顶部或底部,打开它们。图2显示了Windows Store命令栏。在该例中,命令位于屏幕顶部。

DSC0002.jpg

图2
1.2  快速流畅

      快速流畅是Windows 8应用程序的另一个重要原则。在传统的用户界面中使用鼠标时,用户习惯于有一点儿延迟。同样,单击按钮或在屏幕上移动某些对象时,也习惯于有一点儿延迟。这种延迟在触摸模式下是不可接受的。如果在触摸后屏幕没有立即产生什么反映,或者UI没有响应,用户的体验就会很差。

新的Windows Runtime规定,如果一个方法的执行时间超过50ms,就只能异步执行。在.NET框架中,许多API调用既有同步版本,又有异步版本。

      因为同步编程比异步编程更容易创建,所以一般使用API的同步版本。使用C# 5.0中新的异步功能,以及async和await关键字,异步API调用也非常容易使用。第13章介绍了这些新关键字的所有细节。除了使用异步API之外,还应在应用程序中为执行很长时间的任务创建异步API。

      异步编程仅是实现快速流畅这一原则的一部分。如前所述,Windows 8能很好地支持动画,因为它们以自然、真实的方式把用户体验联系在一起,且不会分散注意力。内置控件已经有动画,允许编写出流畅的切换效果,而不是很突然的变化。使用这些内置控件,就不需要定义自定义动画,但如果愿意,也是可以定义自定义动画的。

1.3  可读性

可读性对于任何应用程序都很重要,而Windows 8提供了完整的样式应用规则集。这些规则覆盖了用户体验的所有排版方面,包括可读的字体、颜色和字母间距。例如,Segoe UI字体应用于UI元素(按钮、日期选择器),Calibri字体用于用户读写的文本,Cambria字体用于大文本块。

二  示例应用程序的核心功能

      本节开发的Windows 8示例应用程序用于创建菜单卡。后面看到的菜单和图片都来自我妻子在维也纳市中心开的饭店http://www.kantine.at,欢迎读者光临该饭店。

在该应用程序中,饭店可以创建菜单卡,例如早餐、午餐卡和汤羹卡等。通过这个功能,应用程序使用XAML和C#获得用户的信息,以写入数据,处理菜单卡的图像,以及与应用程序相关的其他任务。

示例应用程序的创建从Windows Store类别中的Blank App (XAML)模板开始,如图3所示。

DSC0003.jpg

图3
2.1  文件和目录

      在根据模板创建的项目中,解决方案包含几个目录和一些文件。Assets目录包含应用程序的徽标(Logo)图像和一个闪屏。Common目录包含从模板中创建和使用的标准样式和实用工具类。在Blank App (XAML)模板中,Common目录只包含样式(文件名为StandardStyles.xaml)。在给项目添加使用项模板的其他功能时,添加特性类。项目中最重要的文件是App.xaml及其代码文件App.xaml.cs,MainPage.xaml及其代码文件MainPage.xaml.cs,以及Package.appxmanifest。XAML和代码文件非常类似于第35章中WPF的结构。

Package.appxmanifest 是一个XML文件,描述了应用程序的打包和功能。用Visual Studio打开这个文件,会打开清单设计器Manifest Designer,如图4所示。其中定义了应用程序名、徽标图像和闪屏。图像所需的像素尺寸显示在这个编辑器中。徽标需要150×150像素,如果应用程序还支持宽徽标(用户可以选择它),则宽徽标需要310×150像素。闪屏需要620×300像素。可以添加PNG或JPG文件。

应用程序的入口点是App类。在这个类中实例化了主页。除了UI的定义之外,也使用该软件包指定了功能和声明。在Capabilities选项卡,应用程序指定是否希望访问麦克风或网络摄像头等设备。在Windows Store中安装应用程序时,会告诉用户应用程序有什么需求。如果没有声明,应用程序就不能使用这些设备。在Declarations选项卡,应用程序声明了它支持的功能,例如,它是否可用于搜索系统;或者它是否提供共享目标,以允许其他应用程序为它提供一些数据。

下面给应用程序添加一些页面。

DSC0004.jpg

图4
2.2  应用程序数据

      对于要在UI中使用的数据,应用程序在DataModel子目录中定义了几个类型。类MenuCard(代码文件MenuCard/DataModel/MenuCard.cs)表示包含应用程序主要数据的菜单卡。这个类定义了用于显示的属性Title、Description和Image。与用于数据绑定的所有类一样,MenuCard也派生自基类BindingBase。BindingBase提供了INotifyPropertyChanged的实现代码。SetProperty方法用属性的set访问器调用,由这个基类实现,用于更改通知。这个基类现在还不存在,3.3小节会使用Visual
Studio项模板来创建它:


using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Imaging;
using Wrox.Win8.Common;
namespace Wrox.Win8.DataModel
{
public class MenuCard : BindableBase
{
private string title;
public string Titled
{
get { return title; }
set
{
SetProperty(ref title, value);
SetDirty();
}
}
private string description;
public string Description
{
get { return description; }
set
{
SetProperty(ref description, value);
SetDirty();
}
}
private ImageSource image;
public ImageSource Image
{
get { return image; }
set { SetProperty(ref image, value); }
}
private string imagePath;
public string ImagePath
{
get { return imagePath; }
set { imagePath = value; }
}
public void SetDirty()
{
IsDirty = true;
}
public void ClearDirty()
{
IsDirty = false;
}
public bool IsDirty { get; private set; }
private readonly ICollection<MenuItem> menuItems =
new ObservableCollection<MenuItem>();
public ICollection<MenuItem> MenuItems
{
get { return menuItems; }
}
public void RestoreReferences()
{
foreach (var menuItem in MenuItems)
{
menuItem.MenuCard = this;
}
}
public override string ToString()
{
return Title;
}
}
}


       包含在MenuCard中的类MenuItem(代码文件MenuCard/DataModel/MenuItem.cs)还定义了带有更改通知的简单属性:

using Wrox.Win8.Common;
namespace Wrox.Win8.DataModel
{
public class MenuItem : BindableBase
{
private string text;
public string Text
{
get { return text; }
set
{
SetProperty(ref text, value);
SetDirty();
}
}
private void SetDirty()
{
if (MenuCard != null)
{
MenuCard.SetDirty();
}
}
private double price;
public double Price
{
get { return price; }
set
{
SetProperty(ref price, value);
SetDirty();
}
}
public MenuCard MenuCard { get; set; }
}
}

  类AddMenuCardInfo(代码文件MenuCard/DataModel/AddMenuCardInfo.cs)用于创建新菜单卡。这个类也是用于数据绑定的简单类型

using Windows.UI.Xaml.Media;
using Wrox.Win8.Common;
namespace Wrox.Win8.DataModel
{
public class AddMenuCardInfo : BindableBase
{
private string title;
public string Title
{
get { return title; }
set { SetProperty(ref title, value); }
}
private string description;
public string Description
{
get { return description; }
set { SetProperty(ref description, value); }
}
private ImageSource image;
public ImageSource Image
{
get { return image; }
set { SetProperty(ref image, value); }
}
private string imageFileName;
public string ImageFileName
{
get { return imageFileName; }
set { SetProperty(ref imageFileName, value); }
}
}
}

      类MenuCardFactory(代码文件MenuCard/DataModel/MenuCardFactory.cs)独立使用,可返回一个菜单卡列表。方法InitMenuCards用于初始化该集合,并把ObservableCollection<MenuCard>赋予cards变量:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace Wrox.Win8.DataModel
{
public class MenuCardFactory
{
private ICollection<MenuCard> cards;
public ICollection<MenuCard> Cards
{
get
{
return cards;
}
}
public void InitMenuCards(IEnumerable<MenuCard> menuCards)
{
cards = new ObservableCollection<MenuCard>(menuCards);
}
private static MenuCardFactory instance = null;
public static MenuCardFactory Instance
{
get
{
return instance ?? (instance = new MenuCardFactory());
}
}
}
}


      这个应用程序用于创建菜单卡,但在第一次启动时,最好向用户显示一些初始的菜单卡。要创建示例数据,可使用MenuCardDataFactory类中的GetSampleMenuCards方法返回一组填充了一些菜单的菜单卡。示例菜单卡的图像存储在Assets文件夹中,从该文件夹中引用,例如Breakfast.jpg:

public static ObservableCollection<MenuCard> GetSampleMenuCards()
{
Uri baseUri = new Uri(&quot;ms-appx:///&quot;);

var cards = new ObservableCollection<MenuCard>();
MenuCard card1 = new MenuCard
{
Title = &quot;Breakfast&quot;
};
card1.MenuItems.Add(new MenuItem
{
Text = &quot;Spezialfrühstück&quot;,
Price = 5.4,
MenuCard = card1
});
card1.MenuItems.Add(new MenuItem
{
Text = &quot;Wiener Frühstück&quot;,
Price = 4.4,
MenuCard = card1
});
card1.MenuItems.Add(new MenuItem
{
Text = &quot;Schinken mit 3 Eiern&quot;,
Price = 4.4,
MenuCard = card1
});
card1.ImagePath = string.Format(&quot;{0}{1}&quot;, baseUri, &quot;Assets/Breakfast.jpg&quot;);
cards.Add(card1);

//... more menu cards in the code download



2.3  应用程序页面

现在向应用程序添加一些UI页面。从模板添加的第一个页面是MainPage.xaml。根据Blank App (XAML)模板,该页面没有提供任何结构,内容是完全可定制的。如果不创建Windows 8游戏或需要特殊布局的其他应用程序,最好使用标准的&#26684;式和样式,把应用程序名放在Windows 8样式规则准确定义的位置上。在开始运行不同的Windows 8应用程序时,会发现它们有一些相&#20284;之处。为了不重复工作,可以直接通过Visual Studio项模板,使用预定义的样式,如图5所示。

DSC0005.jpg

图5
    在示例应用程序中,前面创建的主页用Items Page模板替代。该应用程序创建的其他页面有基本页面(Basic Page)AddMenuCardPage和项页面(Items Page)MenuItemsPage。

    基本页面提供了一个布局,把应用程序名放在用户习惯查看的顶部位置。分割页面(Split Page)把页面分成两半,一半是列表,另一半是细节。

    项页面包含GridView控件,它在一个网&#26684;中显示项列表。要使用项组,可以使用模板Grouped Items Page、Group Detail Page和Item Detail Page。Grouped Items Page用于显示不同的项组,并使用带GroupStyle设置的ListView,以及带分组的CollectionViewSource。Group Detail Page显示一个组及其详细信息,于是为这个任务使用GridView。Item
Detail Page使用RichTextBlock显示一项的细节,允许使用FlipView在项之间切换。






    使用这些模板在项目的Common目录中再添加更多的类:BindableBase可以用作一些数据类的基类,因为它实现了INotifyPropertyChanged接口;LayoutAwarePage是自定义页面的一个新基类,它可以通知旋转更改,提供旋转的可视化状态。BooleanNegationConverter和BooleanToVisibility- Converter是XAML实现IValueConverter的转换器,RichTextColumns类可以与RichTextBlock控件一起用于文本溢出。最后,SuspensionManager用于在应用程序挂起时,存储和加载应用程序的状态。



1. 主页

应用程序的主页如图6所示,它显示了每个菜单卡的标题和图像。

DSC0006.jpg

图6
    为此,只需要对XAML代码(代码文件MainPage.xaml)进行一些小的调整,如下代码所示。在Items Page模板中,XAML代码包含一个GridView作为子元素,有变化的是项模板从默认的Standard250×250ItemTemplate变成MenuCardItemTemplate,再添加一个ItemClick事件处理程序,在单击项时触发它:

<GridView x:Name=&quot;itemGridView&quot;
AutomationProperties.AutomationId=&quot;ItemsGridView&quot;
AutomationProperties.Name=&quot;Items&quot;
TabIndex=&quot;1&quot;
Grid.Row=&quot;1&quot;
Margin=&quot;0,-4,0,0&quot;
Padding=&quot;116,0,116,46&quot;
ItemsSource=&quot;{Binding Source={StaticResource itemsViewSource}}&quot;
ItemTemplate=&quot;{StaticResource MenuCardItemTemplate}&quot;
IsItemClickEnabled=&quot;True&quot;
ItemClick=&quot;OnMenuCardClick&quot;/>



    GridView的源代码用ItemsSource属性定义,它引用了静态资源itemsViewSource。itemsViewSource是在刚刚绑定到Items属性的页面资源中指定的一个简单CollectionViewSource:

<CollectionViewSource
x:Name=&quot;itemsViewSource&quot;
Source=&quot;{Binding Items}&quot;/>
MenuCardItemTemplate在自定义样式文件Styles\MenuCardStyles.xaml中定义。默认模板中的项使用两列建立,而这里的项由两行组成。尺寸较大,且绑定到Image和Title属性上。记住,前面定义的MenuCard类实现了这些属性:
<DataTemplate x:Key=&quot;MenuCardItemTemplate&quot;>
<Grid Margin=&quot;6&quot;>
<Grid.RowDefinitions>
<RowDefinition Height=&quot;*&quot; />
<RowDefinition Height=&quot;Auto&quot; />
</Grid.RowDefinitions>
<Border Background=&quot;{StaticResource
ListViewItemPlaceholderBackgroundThemeBrush}&quot; Width=&quot;450&quot; Height=&quot;450&quot;>
<Image Source=&quot;{Binding Image}&quot; Stretch=&quot;UniformToFill&quot;/>
</Border>
<StackPanel Grid.Column=&quot;1&quot; Margin=&quot;10,0,0,0&quot;>
<TextBlock Text=&quot;{Binding Title}&quot; Style=&quot;{StaticResource ItemTextStyle}&quot;
MaxHeight=&quot;40&quot;/>
</StackPanel>
</Grid>
</DataTemplate>



    前面定义的CollectionViewSource绑定到Items集合上。Items集合在MainPage类的方LoadState法中赋&#20540;(代码文件MenuCard/MainPage.xaml.cs)。LoadState方法的实现代码指定了LayoutAwarePage基类的DefaultViewModel属性。这个属性返回IObservableMap<string, object>,其中任意数据对象都可以赋予一个键名。键名在XAML中用于引用数据。

protected override async void LoadState(Object navigationParameter,
Dictionary<String, Object> pageState)
{
var storage = new MenuCardStorage();
MenuCardFactory.Instance.InitMenuCards(new ObservableCollection<MenuCard>(
await storage.ReadMenuCardsAsync()));
this.DefaultViewModel[&quot;Items&quot;] = MenuCardFactory.Instance.Cards;
}



2. 添加菜单卡页面

    为了添加新的菜单卡,添加了AddMenuCardPage。这里使用的模板只是Basic Page模板。但是,其中没有太多的内容要定义。用户只需要给菜单卡指定标题、描述和图像。UI如图7所示,只需两个文本框、一个按钮和一个Image控件。

DSC0007.jpg

图7
    在AddMenuCard.xaml文件中定义主要控件的XAML代码如下所示。注意这里的两个要点:控件绑定到Image、Title和Description属性上,赋予父控件(Grid)的数据上下文被设置为Item属性:

<Grid Grid.Row=&quot;1&quot; DataContext=&quot;{Binding Item}&quot;>
<Grid.RowDefinitions>
<RowDefinition Height=&quot;100&quot; />
<RowDefinition Height=&quot;300&quot; />
<RowDefinition Height=&quot;*&quot; />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border Grid.Row=&quot;0&quot; Grid.RowSpan=&quot;3&quot; Grid.Column=&quot;0&quot; Grid.ColumnSpan=&quot;2&quot;>
<Image Source=&quot;{Binding Image, Mode=OneWay}&quot; Stretch=&quot;UniformToFill&quot; />
</Border>
<TextBlock Text=&quot;Name:&quot; Style=&quot;{StaticResource TitleTextStyle}&quot; Margin=&quot;20&quot;
VerticalAlignment=&quot;Center&quot; HorizontalAlignment=&quot;Right&quot; />
<TextBox Grid.Column=&quot;1&quot; Text=&quot;{Binding Title, Mode=TwoWay}&quot; Margin=&quot;20&quot;
VerticalAlignment=&quot;Center&quot; />
<TextBlock Grid.Row=&quot;1&quot; Text=&quot;Description:&quot;
Style=&quot;{StaticResource TitleTextStyle}&quot; Margin=&quot;20&quot;
VerticalAlignment=&quot;Center&quot;
HorizontalAlignment=&quot;Right&quot; />
<TextBox Grid.Row=&quot;1&quot; Grid.Column=&quot;1&quot;
Text=&quot;{Binding Description, Mode=TwoWay}&quot;
Margin=&quot;20&quot; MaxHeight=&quot;100&quot; VerticalAlignment=&quot;Center&quot; />
<Button HorizontalAlignment=&quot;Center&quot; VerticalAlignment=&quot;Center&quot;
Visibility=&quot;{Binding ImageUploaded,
Converter={StaticResource visibilityConverter}}&quot; Content=&quot;Upload Image&quot;
Grid.Row=&quot;2&quot; Grid.Column=&quot;0&quot; Grid.ColumnSpan=&quot;2&quot;
Style=&quot;{StaticResource TextButtonStyle}&quot; Click=&quot;OnUploadImage&quot;
Padding=&quot;10&quot; Margin=&quot;20&quot; />
</Grid>



    在代码文件中,Item属性被赋予LoadState方法中AddMenuCardInfo类型的对象(它包含在XAML代码中绑定的属性) (代码文件AddMenuCardPage.xaml.cs):

private AddMenuCardInfo info = new AddMenuCardInfo();

protected override void LoadState(Object navigationParameter,
Dictionary<String, Object> pageState)
{
this.DefaultViewModel[&quot;Item&quot;] = info;
}



3. 菜单项页面

    应用程序的第三个页面是MenuItemsPage,如图8所示。这个页面显示了一个菜单卡中的菜单项,并允许修改数据。

DSC0008.jpg

图8
    这个页面也基于Items Page模板,在LoadState方法中绑定到一组菜单项上(代码文件MenuItems- Page.xaml.cs):

protected override void LoadState(Object navigationParameter,
Dictionary<String, Object> pageState)
{
card = navigationParameter as MenuCard;
if (card != null)
{
this.DefaultViewModel[&quot;Items&quot;] = card.MenuItems;
}
}



    有了3个页面后,就准备导航Windows 8应用程序。

三  应用程序工具栏

     尽管在chrome之前放置内容是Windows 8应用程序的一个重要设计方面,但显然用户需要一种方式与UI交互操作。现在这由新的应用程序工具栏(App Bar)提供。Windows以前的版本默认显示命令,而现在用户可以选择何时显示应用程序命令。

    通过触摸,轻击屏幕的底边界或顶边界时,应用程序工具栏就会显示出来。使用鼠标时,单击鼠标右键,会调用应用程序工具栏。使用键盘时,用户可以单击上下文菜单按钮。

    可以在页面的BottomAppBar和TopAppBar属性中定义应用程序工具栏。大多数应用程序都在底部显示应用程序工具栏。如果应用程序在顶部和底部都使用应用程序工具栏,它们就同时用相同的样式显示出来。

    下面的代码段(代码文件MainPage.xaml)在页面的BottomAppBar属性中定义了一个AppBar元素。在AppBar中,可以使用任何XAML元素定义应用程序工具栏的内容和布局。在这个示例中,添加了两个Button(按钮)控件,它们使用预定义的样式,并给Click事件添加了处理程序:

<Page.BottomAppBar>
<AppBar>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=&quot;50*&quot;/>
<ColumnDefinition Width=&quot;50*&quot;/>
</Grid.ColumnDefinitions>
<StackPanel x:Name=&quot;LeftCommands&quot; Orientation=&quot;Horizontal&quot; Grid.Column=&quot;0&quot;
HorizontalAlignment=&quot;Left&quot;>
<Button Style=&quot;{StaticResource AddAppBarButtonStyle}&quot;
HorizontalAlignment=&quot;Left&quot; Tag=&quot;Add&quot; Click=&quot;OnAddMenuCard&quot; />
<Button Style=&quot;{StaticResource DeleteAppBarButtonStyle}&quot;
HorizontalAlignment=&quot;Left&quot; Tag=&quot;Delete&quot; Click=&quot;OnDeleteMenuCard&quot; />
</StackPanel>
<StackPanel x:Name=&quot;RightCommands&quot; Orientation=&quot;Horizontal&quot; Grid.Column=&quot;1&quot;
HorizontalAlignment=&quot;Right&quot;>
</StackPanel>
</Grid>
</AppBar>
</Page.BottomAppBar>



    在Visual Studio模板生成的样式文件中,已经有一些用于应用程序工具栏的预定义按钮。下面是示例代码使用的样式AddAppBarButtonStyle。这个样式仅使用Segoe UI Symbol字体系列定义了字符的&#20540;,以显示加号。除此之外,还用基本样式AppBarButtonStyle定义了轮廓线字形和TextBlock,来显示按钮的文本。

<Style x:Key=&quot;AddAppBarButtonStyle&quot; TargetType=&quot;Button&quot;
BasedOn=&quot;{StaticResource AppBarButtonStyle}&quot;>
<Setter Property=&quot;AutomationProperties.AutomationId&quot; Value=&quot;AddAppBarButton&quot;/>
<Setter Property=&quot;AutomationProperties.Name&quot; Value=&quot;Add&quot;/>
<Setter Property=&quot;Content&quot; Value=&quot;&quot;/>
</Style>



图9显示了带有应用程序工具栏的应用程序。

DSC0009.jpg

图9


小结:

    本文介绍了编写Windows 8应用程序的许多不同方面。XAML与编写WPF应用程序非常相&#20284;。数据绑定、内容控件和项控件一起使用。利用Visual State Manager处理不同的布局变化。Windows Runtime访问存储器,以读写数据和图像,使用移动存储器。使用FileOpenPicker,通过与用户交互来上传文件。本文还介绍了共享协定,它定义了提供数据的共享源和接收数据的共享目标。

    当然,设计Windows 8应用程序还有许多内容。还有更多的选择器(如联系人选择器),为应用程序提供文件打开选择器的协定;改进的搜索功能(允许应用程序使用toast给用户提供信息)等。





  

《C#高级编程(第8版)》试读电子书免费提供,有需要的留下邮箱,一有空即发送给大家。 别忘啦顶哦!
版权声明:本文为博主原创文章,未经博主允许不得转载。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-134796-1-1.html 上篇帖子: 实验三十五 Windows Server 2012 RDS桌面虚拟化之六VDI虚拟桌面的用户管理和安全防护 下篇帖子: windows7下vs2012+qwt6.1+qt5.3.1的配置注意问题。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表