The document discusses Windows 8 app development. It covers topics like the Windows 8 platform and tools, UI controls like AppBar and FlipView, semantic zoom and grouping in ListView, contracts, notifications, publishing to the Windows Store, and key development points. Visual Studio 2012 is introduced as the development tool. Code examples are provided for various controls and concepts.
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
netmind - Primer Contacto con el Desarrollo de Aplicaciones para Windows 8
1. F O C U S Q U A L I T Y E X P E R I E N C E
Desarrollo Windows 8
Xavier Saladié
xavisf@expert.netmind.es
Barcelona, Noviembre 2012
Desarrollo Windows 8
Contenidos
Plataforma Aplicaciones Windows 8
Tools
UI Controls
Appbar
FlipView
ListView, Grouping y Semantic zoom
Contratos
Notificaciones
Puntos claves para publicar en el Store
2.
3.
4. Tu aplicación
Llamadas Directas
Process.exe (C#,VB.Net, C++)
o WinRT APIs
Core OS
WWAHost.exe (HTML/JS)
Llamadas Delegadas Broker
Contenedor+ Código Firmado y Verificado
AppXManifest
5. La app toma 5s para La App no es
entrar en suspensión notificada antes de
terminarse
Usuario
Lanza
App
Las apps son informadas
cuando se las ha reanudado
Pantalla
Splash
6. • App usan sus datos y los almacena localmente
Local
Storage
La información se
sincroniza desde la
cuenta Microsoft del
usuario
7.
8. The development tools are FREE!
If you use a higher SKU, it just works!
Files / Assets
AppXManifest.xml
BlockMap
Signature
Zip Central
Directory
.appx package
15. Se utiliza para mostrar las acciones de una ventana.
Se mantiene oculta.
Puede cambiar en función de la pantalla.
Se activa con el botón derecho
Iconos: http://msdn.microsoft.com/en-us/library/windows/apps/hh770557.aspx
24. internal List<GroupInfoList<object>> GetGroupsByCategory()
{ List<GroupInfoList<object>> groups = new List<GroupInfoList<object>>();
var query = from item in Collection orderby ((Item)item).Category
group item by ((Item)item).Category into g
select new { GroupName = g.Key, Items = g };
foreach (var g in query)
{ GroupInfoList<object> info = new GroupInfoList<object>();
info.Key = g.GroupName;
foreach (var item in g.Items)
{ info.Add(item); }
groups.Add(info); }
return groups; }
public class GroupInfoList<T> : List<object>
{
public object Key { get; set; }
public new IEnumerator<object> GetEnumerator()
{ return (System.Collections.Generic.IEnumerator<object>)base.GetEnumerator();} }
List<GroupInfoList<object>> dataCategory = _storeData.GetGroupsByCategory();
cvs1.Source = dataCategory;
32. //override in app the handler to OnWindowCreated
protected override void OnWindowCreated(WindowCreatedEventArgs args)
{ // Register QuerySubmitted handler for the window at window creation time
SearchPane.GetForCurrentView().QuerySubmitted +=
new TypedEventHandler<SearchPane, SearchPaneQuerySubmittedEventArgs>(OnQuerySubmitted);}
private void OnQuerySubmitted(SearchPane sender, SearchPaneQuerySubmittedEventArgs args)
{ // Process the query
if (MainPage.Current != null)
{ MainPage.Current.ProcessQueryText(args.QueryText);} }
33.
34. protected override void OnNavigatedTo(NavigationEventArgs e)
{ // Register the current page as a share source.
this.dataTransferManager = DataTransferManager.GetForCurrentView();
this.dataTransferManager.DataRequested += new TypedEventHandler<DataTransferManager,
DataRequestedEventArgs>(this.OnDataRequested); }
protected override void OnNavigatedFrom(NavigationEventArgs e)
{ // Unregister the current page as a share source.
this.dataTransferManager.DataRequested -= new TypedEventHandler<DataTransferManager,
DataRequestedEventArgs>(this.OnDataRequested); }
// When share is invoked the event handler will be called to populate the datapackage.
private void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs e)
{ bool succeeded = false;
string dataPackageText = TextToShare.Text;
if (!String.IsNullOrEmpty(dataPackageText))
{ DataPackage requestData = e.request.Data;
requestData.Properties.Title = TitleInputBox.Text;
requestData.Properties.Description = DescriptionInputBox.Text;
requestData.SetText(dataPackageText);
succeeded = true; }
else
{ e.request.FailWithDisplayText("Enter the text you would like to share and try again."); }
return succeeded; }
35. Permite recibir información de otras apps.
Puede permitir distintos formatos.
Se activa al seleccionar la app dentro de Share.
36. //On App we override the event for Share Targeting Activated and navigate to the Page receiving data
protected override void OnShareTargetActivated(ShareTargetActivatedEventArgs args)
{ var rootFrame = new Frame();
rootFrame.Navigate(typeof(MainPage), args.ShareOperation);
Window.Current.Content = rootFrame;
Window.Current.Activate(); }
//On NavigateTo event of the page receiving data, we just do it asynchronously
protected override async void OnNavigatedTo(NavigationEventArgs e)
{ // It is recommended to only retrieve the ShareOperation object in the activation handler, return as
// quickly as possible, and retrieve all data from the share target asynchronously.
this.shareOperation = (ShareOperation)e.Parameter;
await Task.Factory.StartNew(async () =>
{ // Retrieve the data package properties.
this.sharedDataTitle = this.shareOperation.Data.Properties.Title;
this.sharedDataDescription = this.shareOperation.Data.Properties.Description;
this.sharedThumbnailStreamRef = this.shareOperation.Data.Properties.Thumbnail;
this.shareQuickLinkId = this.shareOperation.QuickLinkId;
// Retrieve the data package content.
if (this.shareOperation.Data.Contains(StandardDataFormats.Uri))
{ // The GetUriAsync() API will throw if there was an error retrieving data.
try { this.sharedUri = await this.shareOperation.Data.GetUriAsync(); }
catch (Exception ex)
{ … } }
40. IWideTileNotificationContent tileContent = null;
ITileWideImageAndText01 wideContent = TileContentFactory.CreateTileWideImageAndText01();
wideContent.RequireSquareContent = false;
wideContent.TextCaptionWrap.Text = "The image is in the appx package";
wideContent.Image.Src = "ms-appx:///images/redWide.png";
wideContent.Image.Alt = "Red image";
tileContent = wideContent;
// Users can resize tiles to square or wide.
// Apps can choose to include only square assets (meaning the app's tile can never be wide), or
// include both wide and square assets (the user can resize the tile to square or wide).
// Apps cannot include only wide assets. Apps that support being wide should include square tile
// notifications since users determine the size of the tile.
// create the square template and attach it to the wide template
ITileSquareText04 squareContent = TileContentFactory.CreateTileSquareText04();
squareContent.TextBodyWrap.Text = "Hello World! My very own tile notification";
tileContent.SquareContent = squareContent;
TileUpdateManager.CreateTileUpdaterForApplication().Update(tileContent.CreateNotification());
http://msdn.microsoft.com/en-us/library/windows/apps/hh913756.aspx
http://msdn.microsoft.com/en-us/library/windows/apps/xaml/Hh868255(v=win.10).aspx
44. Permite añadir segundos accesos a una app.
El usuario siempre debe aprobar este segundo tile.
Es posible actualizar su contenido.
45. // Prepare package images for use as the Tile Logo and small Logo in our tile to be pinned
Uri logo = new Uri("ms-appx:///Assets/squareTile-sdk.png");
Uri smallLogo = new Uri("ms-appx:///Assets/smallTile-sdk.png");
// In this sample, we'll pass in the date and time the secondary tile was pinned.
public const string SecTileId = "SecondaryTileId"
string tArguments = SecTileId + " WasPinnedAt=" + DateTime.Now.ToLocalTime().ToString();
// Create a 1x1 Secondary tile
SecondaryTile secTile = new SecondaryTile(SecTileId, "Title text", "Name when searching",
tArguments, TileOptions.ShowNameOnLogo, logo);
secTile.ForegroundText = ForegroundText.Dark;
secTile.SmallLogo = smallLogo;
// OK, the tile is created and we can now attempt to pin the tile.
bool isPinned = await SecTile.RequestCreateForSelectionAsync(
MainPage.GetElementRect((FrameworkElement)sender),Windows.UI.Popups.Placement.Below);
// Typical OnLaunched override Method of App.xaml.cs
async protected override void OnLaunched(LaunchActivatedEventArgs args)
{ if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
{ // Do an asynchronous restore
await RestoreData() }
if (Window.Current.Content == null)
{ var rootFrame = new Frame();
rootFrame.Navigate(typeof(MainPage));
((MainPage)rootFrame.Content).LaunchArgs = args;
Window.Current.Content = rootFrame; }
else
{ if (args.Arguments != “”)
{ //Inspect content of args and navigate where is needed } }
Window.Current.Activate(); }
46.
47.
48. IToastNotificationContent toastContent = null;
IToastImageAndText03 templateContent = ToastContentFactory.CreateToastImageAndText03();
templateContent.TextHeadingWrap.Text = "Heading text that wraps";
templateContent.TextBody.Text = "Body text";
templateContent.Image.Src = "images/toastImageAndText.png";
templateContent.Image.Alt = "Placeholder image";
toastContent = templateContent;
// Set the launch activation context parameter on the toast.
toastContent.Launch = "Context123";
// Create a toast from content
ToastNotification toast = toastContent.CreateNotification();
// create a ToastNotifier object to show the toast
ToastNotificationManager.CreateToastNotifier().Show(toast);
49.
50. <UserControl
// In app.OnLaunched and in app.OnSearchActivated we register event for managing settings
x:Class="ContosoCookbook.PreferencesUserControl"
// Register handler for CommandsRequested events from the settings pane
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
SettingsPane.GetForCurrentView().CommandsRequested += OnCommandsRequested;
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
void OnCommandsRequested(SettingsPane sender, SettingsPaneCommandsRequestedEventArgs args)
{ // Add an About command
xmlns:local="using:ContosoCookbook"
var about = new SettingsCommand("about", "About", (handler) =>
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
{ var settings = new SettingsFlyout();
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
settings.Content = new AboutUserControl();
mc:Ignorable="d"
settings.HeaderBrush = new SolidColorBrush(_background);
d:DesignHeight="300" = new SolidColorBrush(_background);
settings.Background
d:DesignWidth="400"> = "About";
settings.HeaderText
<Grid>
settings.IsOpen = true; });
args.Request.ApplicationCommands.Add(about);
<ToggleSwitch x:Name="Remember" Header="Remember where I was" Toggled="OnToggled" />
</Grid> Preferences command
// Add a
var preferences = new SettingsCommand("preferences", "Preferences", (handler) =>
</UserControl>
{ var settings = new SettingsFlyout();
settings.Content = new PreferencesUserControl();
settings.HeaderBrush = new SolidColorBrush(_background);
settings.Background = new SolidColorBrush(_background);
settings.HeaderText = "Preferences";
settings.IsOpen = true; });
args.Request.ApplicationCommands.Add(preferences); }
51.
52.
53. private void Button_Click(object sender, RoutedEventArgs e)
{
Flyout flyOut = new Flyout();
flyOut.PlacementTarget = sender as UIElement;
flyOut.Placement = PlacementMode.Top;
flyOut.Content = new FlyoutUserControl();
flyOut.IsOpen = true;
}
54.
55. // Create the message dialog and set its content and title
var msgDlg = new MessageDialog(“Updates found. Would you like to install?", "Updates");
// Add commands and set their callbacks
msgDlg.Commands.Add(new UICommand("Don't install", (command) =>
{ rootPage.NotifyUser("'Don't install' command has been selected.",
NotifyType.StatusMessage); }));
msgDlg.Commands.Add(new UICommand("Install updates", (command) =>
{ rootPage.NotifyUser("'Install updates' command has been selected.",
NotifyType.StatusMessage); }));
// Set the command that will be invoked by default
msgDlg.DefaultCommandIndex = 1;
// Show the message dialog
await msgDlg .ShowAsync();
56.
57.
58.
59. Escenario Deberías….
using Windows.Networking.Connectivity;
...
public static bool isConnected()
{ var p=NetworkInformation.GetInternetConnectionProfile();
if (p!=null) {
if (p.GetNetworkConnectivityLevel()==NetworkConnectivityLevel.InternetAccess)
{ return true }
else
{ return false; } }
else { return false; } }
62. Y para terminar…
Foros en español
http://social.msdn.microsoft.com/Forums/es-ES/w8metroes/
Foros en inglés
http://social.msdn.microsoft.com/Forums/en-US/category/windowsapps
Alias de Soporte Desarrollo Windows 8
sopw8@microsoft.com
63. Introducción al desarrollo de aplicaciones Metro para Windows 8
http://blogs.msdn.com/b/esmsdn/archive/2012/07/18/introducci-243-n-al-
desarrollo-de-aplicaciones-metro-para-windows-8.aspx
Cursos de Formación de Windows 8
http://blogs.msdn.com/b/esmsdn/archive/2012/09/04/cursos-de-formaci-243-n-
de-windows-8.aspx
Tips & Tricks de desarrollo para Windows 8
http://blogs.msdn.com/b/esmsdn/archive/2012/08/08/tips-amp-tricks-de-
desarrollo-para-windows-8.aspx
Windows 8 Metro style app samples
http://code.msdn.microsoft.com/windowsapps
Problemas comunes para pasar la certificación de Windows 8
http://blogs.msdn.com/b/esmsdn/archive/2012/07/31/problemas-comunes-
para-pasar-la-certificaci-243-n-de-windows-8.aspx
V3.0 Certification requirements
http://msdn.microsoft.com/en-us/library/windows/apps/jj128432.aspx
64. F O C U S Q U A L I T Y E X P E R I E N C E
Preguntas y aclaraciones
Muchas gracias por su atención
Xavier Saladié
xavisf@expert.netmind.es