Ignorer les commandes du Ruban
Passer au contenu principal
Accueil

 
Accueil
avril 19
Windows Phone : Tile (addendum)

Suite à quelques messages me demandant comment mettre à jour le “tile” depuis un background agent, voici la procédure à suivre.

En effet, les fonctions utilisées, pour la création de l’image, doivent être appelées dans le contexte du thread UI. Un “BeginInvoke” de résoudre cette contrainte.

Il suffit de mettre le code de l’article précédant à l’endroit du commentaire dans le code qui suit :

protected override void OnInvoke(ScheduledTask task)
{
   if (task is PeriodicTask)
   {
      AutoResetEvent e = new AutoResetEvent(false);
      Deployment.Current.Dispatcher.BeginInvoke(() =>
      {
         // Le code pour mettre a jour le Tile
         e.Set();
      });
      e.WaitOne();
   }
   NotifyComplete();
}
avril 02
Windows Phone, Facebook, Twitter…

Partagé un lien sur Facebook, Twitter depuis une application se fait très facilement. L’objet “ShareLinkTask” s’occupant de tout Smile.

ShareLinkTask slt = new ShareLinkTask()
               {
                    Title ="test",
                    Message="test msg",
                    LinkUri=new Uri("http://www.neomytic.be")
               };
slt.Show();

Pour partager un statut, c’est aussi simple grâce à l’objet “SharedStatusTask”.

avril 02
Windows Phone : Tile

Les tiles (tuiles) utilisé dans le windows Phone sont composé the trois éléments :

  • Une image
  • Un text
  • Un compteur

Référencer ces éléments est réalisé via l’objet « ShellTile », via lequel l’on peut rajouter, modifier ou supprimer des « tiles ».

Dans certains cas, il est nécessaire de créer un « tile » contenant des informations dynamiques. Cela se fait en créant une image, de la sauvegarder dans « l’IsolatedStorage » et de la référencer.

Ci-dessous la procédure à suivre.

La première étape est de créé une image de 173 pixels sur 173 pixels (grandeur du « tile »).

 

var wb = new WriteableBitmap(173, 173);

 

Dans cette image, on va « composer » notre nouveau « tile » via un ensemble d’objets graphiques.

Une image de référence reprise des ressources de notre projet par exemple (dans l’exemple, j’utilise l’image du « tile » par défaut). A noter que la propriété « Opacity » me permet d’assombrir l’image afin que le texte ressort plus).

 

BitmapImage img = new BitmapImage();
img.SetSource(Application.GetResourceStream(new Uri("Background.png", UriKind.Relative)).Stream);
var imgbkg = new Image
     {
          Opacity = 0.7,
          Height = 173,
          Width = 173,
          Stretch = Stretch.UniformToFill,
          Source = img
     };
wb.Render(imgbkg, new TranslateTransform());

 

Du texte.

 

var text = new TextBlock
{
     Text = "Hello",
     Foreground = new SolidColorBrush(Colors.White),
     FontFamily = new FontFamily("Segoe WP Black"),
     FontSize = 30
};
wb.Render(text, new TranslateTransform { X = 167 - text.ActualWidth, Y = 6 });

 

Une forme géométrique.

 

var rect = new Rectangle
{
     Width = text.ActualWidth + 4,
     Height = text.ActualHeight + 4,
     Stroke = new SolidColorBrush(Colors.Yellow),
};
wb.Render(rect, new TranslateTransform { X = 165 - text.ActualWidth, Y = 4 });

 

Après avoir “composer” notre image, on force celle-ci à se redessiner.

 

wb.Invalidate();

 

Cette nouvelle image, on DOIT la sauvegarder dans notre IsolatedStorage dans un répertoire spécifique « isostore:/Shared/ShellContent/» (si on la met autre part, cela ne fonctionne pas).

 

using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
     if (!isf.DirectoryExists("Shared"))
     {
          isf.CreateDirectory("Shared");
     }
     if (!isf.DirectoryExists("Shared/ShellContent"))
     {
          isf.CreateDirectory("Shared/ShellContent");
     }
     using (IsolatedStorageFileStream fs = isf.CreateFile("/Shared/ShellContent/customtile"))
     {
          wb.SaveJpeg(fs, 173, 173, 0, 80);
     }
}

 

Il ne nous reste plus qu’à modifier notre « tile » pour référencer notre image. Dans l’exemple, je modifie le « tile » principal.

 

Uri isostoreURI = new Uri("isostore:/Shared/ShellContent/customtile", UriKind.Absolute);
ShellTile.ActiveTiles.First().Update(new StandardTileData() { BackgroundImage = isostoreURI, Count=0, Title="" });
mars 07
Windows Phone 7–SkyDrive

Changeant de Windows Phone, je me suis posé la question sur le backup/restore d’un téléphone à un autre. Malheureusement, pas de possibilité de sauvegarder/backuper les données de mes applications/jeux.

Sur ce constat, j’ai exploré les possibilités pour m’appuyer sur SkyDrive. En effet, mon téléphone est connecté, via mon Live ID, sur les services Live de Microsoft. Donc, pourquoi ne pas permettre de faire un export de mes données sur SkyDrive, afin de les importer ultérieurement…

Première étape : visualiser mes fichiers sur SkyDrive depuis mon PC. Ayant trouvé un tutorial sur « MonWindowsPhone.com », je ne vais pas m’étendre plus sur le sujet, et je vous conseille d’aller jeter un œil sur l’article d’Arnaud Deschamps de MonWindowsPhone. Il explique comment accéder à SkyDrive depuis son PC sans passer via un browser, ainsi que des intégrations de SkyDrive dans les applications “standard” du Windows Phone.

Deuxième étape : télécharger les Tools et SDK. Via le lien suivant, le SDK est téléchargeable, et la documentation disponible. Une documentation plus spécifique est disponible ici.

Troisième étape : expérimenter l’accès à SkyDrive depuis mon Windows Phone.

Avant d’interagir avec les services Live, il faut s’authentifier. L’objet LiveAuthClient effectue cette opération en affichant à l’utilisateur un écran demandant le nom d’utilisateur et le mot de passe.

Remarque : l’authentification est interactive ! Donc pas moyen de faire une connexion dans un « Background Agent ». Il faut que la partie graphique de l’application soit initialisée, donc pas d’authentification dans les fonctions « Application_Launching », …

Le premier paramètre de LiveAuthClient définit l’identification du client (« ClientID »). Vous pouvez en générer un en suivant ce lien suivant : https://manage.dev.live.com/. Dans mon code exemple, je mets la valeur "1234567890123456". L’event LoginCompleted retourne à l’application le résultat de l’authentification.

 

LiveAuthClient lac = new LiveAuthClient("1234567890123456", "http://oauth.live.com/desktop");
private void button1_Click(object sender, RoutedEventArgs e)
{
     lac.LoginCompleted +=new EventHandler<LoginCompletedEventArgs>(lac_LoginCompleted);
     List<String> l = new List<string>() { "wl.basic", "wl.photos", "wl.skydrive", "wl.offline_access", "wl.signin", "wl.skydrive_update"};
     lac.LoginAsync(l);
}
void lac_LoginCompleted(object sender, LoginCompletedEventArgs e)
{
}

 

Après l’authentification, l’accès aux fichiers. On énumère les objets dans la racine « me/skydrive » du SkyDrive. Le suffixe « /files » permet de récupérer les éléments.

 

private void EnumRootFolder_Click(object sender, RoutedEventArgs e)
{
     LiveConnectClient clientFolder = new LiveConnectClient(lac.Session);
     clientFolder.GetCompleted += new EventHandler<LiveOperationCompletedEventArgs>(clientFolder_GetCompleted);
     clientFolder.GetAsync("me/skydrive/files");
}

 

En retour les services live renvoient la liste des éléments sous forme d’un fichier JSON. Ci-dessous une partie du résultat. (Les “------------ “ remplacent mes identifiants uniques)

 

{

"data": [

{

"id": "folder. ------------.------------",

"from": {

"name": "Christophe Peerens",

"id": "------------"

},

"name": "Les puces et le chocolas",

"description": "",

"parent_id": "folder. ------------",

"upload_location": "https://apis.live.net/v5.0/folder. ------------.------------!116/files/",

"is_embeddable": true,

"count": 1,

"link": "https://skydrive.live.com/redir.aspx?cid\u003d------------\u0026page\u003dview\u0026resid\u003d------------!116\u0026parid\u003d------------!136",

"type": "album",

"shared_with": {

"access": "People with a link"

},

"created_time": "2007-01-02T13:58:27+0000",

"updated_time": "2011-04-02T07:27:55+0000"

}, {

"id": "folder. ------------.------------!137",

"from": {

"name": "Christophe Peerens",

"id": "------------"

},

"name": "Public",

"description": null,

"parent_id": "folder. ------------",

"upload_location": "https://apis.live.net/v5.0/folder. ------------.------------!137/files/",

"is_embeddable": true,

"count": 1,

"link": "https://skydrive.live.com/redir.aspx?cid\u003d------------\u0026page\u003dview\u0026resid\u003d------------!137\u0026parid\u003d------------!136",

"type": "folder",

"shared_with": {

"access": "Everyone (public)"

},

"created_time": "2009-01-25T13:21:27+0000",

"updated_time": "2011-05-18T07:08:33+0000"

}, {

}, {

}, {

}, {

}

]

}

 

Dans l’event handler, le paramètre e donne le fichier JSON en format RAW, mais aussi une interprétation sous forme de collection de celui-ci. Une petite gymnastique de casting, et les informations sont disponibles.

 

void clientFolder_GetCompleted(object sender, LiveOperationCompletedEventArgs e)
{
     if (e.Result != null)
     {
          foreach (var o in e.Result)
          {
               foreach (var oo in ((System.Collections.Generic.List<object>)(o.Value)))
               {
                    System.Collections.Generic.Dictionary<string, object> entry = (System.Collections.Generic.Dictionary<string, object>)oo;
                    String id = (string)entry["id"];
                    String name = (string)entry["name"];
                    String type = (string)entry["type"];
               }
          }
     }
}

 

Ci-dessous le code complet qui permet de naviguer dans les répertoires SkyDrive.

XAML:

<phone:PhoneApplicationPage 
    x:Class="SkyDriveExplorer.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    shell:SystemTray.IsVisible="True" Loaded="PhoneApplicationPage_Loaded">
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <ListBox ItemsSource="{Binding}" Margin="0,0,0,0" Name="lstFolder" SelectionChanged="lstFolder_SelectionChanged">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <TextBlock Text="{Binding Name}" TextWrapping="Wrap" Margin="0,0,0,0" FontWeight="Bold"/>
                            <TextBlock Text="{Binding Id}" TextWrapping="Wrap" Margin="20,0,0,0" />
                            <TextBlock Text="{Binding Type}" TextWrapping="Wrap" Margin="20,0,0,0" />
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </Grid>
    </Grid>
 
</phone:PhoneApplicationPage>

 

Code:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using Microsoft.Live;
using Microsoft.Phone.Controls;
namespace SkyDriveExplorer
{
    public partial class MainPage : PhoneApplicationPage
    {
        public class SkyDriveListBoxItem : INotifyPropertyChanged, INotifyPropertyChanging
        {
            private String _Id;
            public String Id
            {
                get
                {
                    return _Id;
                }
                set
                {
                    NotifyPropertyChanging("Id");
                    _Id = value;
                    NotifyPropertyChanged("Id");
                }
            }
            private String _Name;
            public String Name
            {
                get
                {
                    return _Name;
                }
                set
                {
                    NotifyPropertyChanging("Name");
                    _Name = value;
                    NotifyPropertyChanged("Name");
                }
            }
            private String _Type;
            public String Type
            {
                get
                {
                    return _Type;
                }
                set
                {
                    NotifyPropertyChanging("Type");
                    _Type = value;
                    NotifyPropertyChanged("Type");
                }
            }
            #region INotifyPropertyChanged Members
            public event PropertyChangedEventHandler PropertyChanged;
            private void NotifyPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
            #endregion
            #region INotifyPropertyChanging Members
            public event PropertyChangingEventHandler PropertyChanging;
            private void NotifyPropertyChanging(string propertyName)
            {
                if (PropertyChanging != null)
                {
                    PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
                }
            }
            #endregion
        }
        public ObservableCollection<SkyDriveListBoxItem> folderitems = new ObservableCollection<SkyDriveListBoxItem>();
        public MainPage()
        {
            InitializeComponent();
            DataContext = folderitems;
        }
        String strFolderName = "me/skydrive";
        // replace de CID
        static LiveAuthClient lac = new LiveAuthClient("0000000099999999", "http://oauth.live.com/desktop");
        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
        }
        private void Login()
        {
            lac.LoginCompleted += new EventHandler<LoginCompletedEventArgs>(lac_LoginCompleted);
            List<String> l = new List<string>() { "wl.basic", "wl.photos", "wl.skydrive", "wl.offline_access", "wl.signin", "wl.skydrive_update" };
            lac.LoginAsync(l);
        }
        void lac_LoginCompleted(object sender, LoginCompletedEventArgs e)
        {
            if (e.Status == LiveConnectSessionStatus.Connected)
            {
                ScanFolder();
            }
        }
        void ScanFolder()
        {
            LiveConnectClient clientFolder = new LiveConnectClient(lac.Session);
            clientFolder.GetCompleted += new EventHandler<LiveOperationCompletedEventArgs>(clientFolder_GetCompleted);
            clientFolder.GetAsync(strFolderName+"/files");
        }
        void clientFolder_GetCompleted(object sender, LiveOperationCompletedEventArgs e)
        {
            if (e.Result != null)
            {
                Dispatcher.BeginInvoke(() =>
                    {
                        folderitems.Clear();
                        foreach (var o in e.Result)
                        {
                            foreach (var oo in ((System.Collections.Generic.List<object>)(o.Value)))
                            {
                                System.Collections.Generic.Dictionary<string, object> entry = (System.Collections.Generic.Dictionary<string, object>)oo;
                                folderitems.Add( new SkyDriveListBoxItem() { Id = (string)entry["id"], Name = (string)entry["name"], Type = (string)entry["type"] } );
                            }
                        }
                    });
            }
        }
        private void lstFolder_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (lstFolder.SelectedIndex == -1)
            {
                return;
            }
            if ((((SkyDriveListBoxItem)lstFolder.SelectedItem).Type == "folder") || (((SkyDriveListBoxItem)lstFolder.SelectedItem).Type == "album"))
            {
                NavigationService.Navigate(new Uri("/MainPage.xaml?folderid=" + ((SkyDriveListBoxItem)lstFolder.SelectedItem).Id, UriKind.RelativeOrAbsolute));
            }
            lstFolder.SelectedIndex = -1;
        }
        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
            if (lac.Session == null)
            {
                Login();
            }
            else
            {
                String strParamFolderName = "";
                if (NavigationContext.QueryString.TryGetValue("folderid", out strParamFolderName))
                {
                    strFolderName = strParamFolderName;
                    ScanFolder();
                }
            }
        }
    }
}
mars 06
Comment [éviter de] perdre du temps pour une bêtise.

Je viens de perdre du temps à cause d’une bêtise !

Visual Studio permet de changer le nom d’une variable très facilement. Cela se fait via clic droit sur la variable -> refactor -> rename.

Jusque-là, pas de soucis Smile

Après je teste mon application, et mon UI ne se met pas à jour comme avant. Ayant rajouté du code, je commence à debugger… Pour en arriver à me rendre compte que « NotifyPropertyChanged » et « NotifyPropertyChanged » ne renvoient pas la bonne propriété.

 

Example:

  • Avant le “rename”
private string _City;
public string Citty
{
     get
     {
          return _City;
     }
     set
     {
          if (_City != value)
          {
               NotifyPropertyChanging("Citty");
               _City = value;
               NotifyPropertyChanged("Citty");
          }
     }
}
  • Après le “rename”
private string _City;
public string City
{
     get
     {
          return _City;
     }
     set
     {
          if (_City != value)
          {
               NotifyPropertyChanging("Citty");
               _City = value;
               NotifyPropertyChanged("Citty");
          }
     }
}

Le “rename” n’a pas changé le nom de la propriété dans les fonctions “NotifyPropertyChangXXX”!

 

Une petite recherche pour trouver un code qui permet de faire le check automatique si la propriété existe m’a mené ici.

[Conditional("DEBUG")]
[DebuggerStepThrough]
public void VerifyPropertyName(string propertyName)
{
     // Verify that the property name matches a real,
     // public, instance property on this object.
     if (TypeDescriptor.GetProperties(this)[propertyName] == null)
     {
          string msg = "Invalid property name: " + propertyName;
          if (this.ThrowOnInvalidPropertyName)
               throw new Exception(msg);
          else
               Debug.Fail(msg);
     }
}

 

Mais cela ne fonctionne pas sous Windows Phone 7 Sad smile. L’objet “TypeDescriptor” n’existant pas sous Windows Phone 7!

L’adaptation pour Windows Phone :

[Conditional("DEBUG")]
[DebuggerStepThrough]
public void VerifyPropertyName(string propertyName)
{
     PropertyInfo pinfo = this.GetType().GetProperty(propertyName);
     if (pinfo == null)
     {
          System.Diagnostics.Debugger.Break();
     }
}

 

Il suffit de vérifier si la propriété existe dans les fonctions « NotifyPropertyChanged » et « NotifyPropertyChanged ».

private void NotifyPropertyChanged(string propertyName)
{
     VerifyPropertyName(propertyName);
     if (PropertyChanged != null)
     {
          PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
     }
}
private void NotifyPropertyChanging(string propertyName)
{
     VerifyPropertyName(propertyName);
     if (PropertyChanging != null)
     {
          PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
     }
}
novembre 30
Testez Windows Phone 7.5 depuis Android ou iOS

Il suffit d’aller sur le lien http://aka.ms/wpdemo via le navigateur internet de votre smartphone iOS ou Android. Une émulation de WP7.5 se met alors à tourner

octobre 20
Formater du code source dans les Blogs

En écrivant les derniers articles, je voulais formater le code source example.

Après quelques recherches, je suis “tombé” sur un “add-on” pour Windows Live Writer.

Content du service offert, je vous partage le lien : http://www.amergerzic.com/post/WLWSourceCodePlugin.aspx

octobre 19
GPS – Windows Phone 7 – Step by step

Dans le cadre des sessions sur Windows Phone 7.5, les démonstrations peuvent être reproduites en suivant les étapes décrites ci-dessous.

Les outils sont téléchargeable gratuitement via le lien suivant : http://create.msdn.com.

 

As part of the sessions on Windows Phone 7.5, the demonstrations may be reproduced by following the steps below.

The tools are downloadable for free via the following link: http://create.msdn.com.

 

Démonstration: utilisation du GPS

Demonstration: using the GPS

  • Créez un nouveau projet « Silverlight for Windows Phone - Windows Phone Application ».
  • Create a new "Silverlight for Windows Phone - Windows Phone Application" project.


  • Sélectionnez la plateforme cible 7.1.
  • Select the target OS 7.1.


  • Dans la page principale, rajouter via la « Toolbox », un objet de type « map ». Associer via la propriété « source » une image.
  • In the main page, add through the "Toolbox", an object of type "map". Link, through the « source » property, an image.


  • Rajouter la propriété « ZoomLevel » Sur l'objet map.
  • Add the "ZoomLevel" property to the map object.
ZoomLevel="16"
GeoCoordinateWatcher geoWatcher = new GeoCoordinateWatcher();
// Constructor
public MainPage()
{
     InitializeComponent();
     geoWatcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(geoWatcher_PositionChanged);
     geoWatcher.Start();
}
void geoWatcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
{
     Dispatcher.BeginInvoke(() =>
     {
          map1.Center = e.Position.Location;
     });
}
  • Compilez et testez dans l'émulateur.
  • Compile and test inside the emulator.


 

Attention: La couverture GPS n'est pas garantie. Il est à la responsabilité du développeur d'en tenir compte dans son développement. De même, l'objet « Map » nécessite une connexion data.

Warning: The GPS coverage is not guaranteed. It is the responsibility of the developer to take this into account in its development. Similarly, the object "Map" requires a data connection.

octobre 19
Accelerometer – Windows Phone 7 – Step by step

Dans le cadre des sessions sur Windows Phone 7.5, les démonstrations peuvent être reproduites en suivant les étapes décrites ci-dessous.

Les outils sont téléchargeable gratuitement via le lien suivant : http://create.msdn.com.

 

As part of the sessions on Windows Phone 7.5, the demonstrations may be reproduced by following the steps below.

The tools are downloadable for free via the following link: http://create.msdn.com.

 

Démonstration: utilisation de l'accéléromètre

Demonstration: using the accelerometer

  • Créez un nouveau projet « Silverlight for Windows Phone - Windows Phone Application ».
  • Create a new "Silverlight for Windows Phone - Windows Phone Application" project.


  • Sélectionnez la plateforme cible 7.1.
  • Select the target OS 7.1.


  • Dans la page principale, rajouter via la « Toolbox », un objet de type image. Associer via la propriété « source » une image.
  • In the main page, add through the "Toolbox", an object of type image. Link, through the « source » property, an image.


  • Rajouter le code suivant dans le XAML de l'image.
  • Add the following code inside the Image in the XAML.
<Image ………>  
    <Image.Projection> 
         <PlaneProjection x:Name="Proj">  
         </PlaneProjection> 
    </Image.Projection> 
</Image>
  • Dans le projet, ajoutez une référence vers « Microsoft.devices.Sensors ».
  • Inside the project, add a reference to « Microsoft.devices.Sensors ».
  • Dans le code, créez un objet de type « Accelerometer ».
  • Inside the code, create an object of type « Accelerometer ».
Accelerometer acc = new Accelerometer();
  • Dans le constructeur de la page, rajouter l'évènement « ReadingChanged » et appelez la méthode « Start » sur l'objet accéléromètre.
  • In the constructor of the page, add the event "ReadingChanged" and call the "Start" method on the accelerometer object.
// Constructor 
public MainPage() 
{  
    InitializeComponent();  
    acc.ReadingChanged += new EventHandler<AccelerometerReadingEventArgs>(acc_ReadingChanged);  
    acc.Start(); 
}
  • Dans l'évènement "ReadingChanged ", implémentez la projection sur l'image.
  • In the event "ReadingChanged", implement the projection onto the image.
void acc_ReadingChanged(object sender, AccelerometerReadingEventArgs e) 
{  
    Dispatcher.BeginInvoke(() =>  
        {  
            Proj.RotationX = e.Z * 90;  
            Proj.RotationZ = e.X * -90;  
        }); 
}
  • Compilez et testez dans l'émulateur.
  • Compile and test inside the emulator.

octobre 18
Windows Phone 7.5 Academic Tour.

L'académique tour a commencé. David Hernie vous en avait parlé sur son blog.

Les slides sont disponible ici.

Lors de la session, plusieurs démonstrations sont réalisées. Je vous invite à trouver les « post » permettant de refaire certaines de ces démonstrations.

Pour l'aspect pratique, vous avez besoin des outils de développement. Ceux-ci peuvent être téléchargés ici.

Si vous voulez plus de lien concernant le développement Windows Phone, je vous conseille cet article de David.

 

The academic tour began. David Hernie already talked about on his blog.

The slides are available here.

During the session, several demonstrations are conducted. I invite you to find the "post" to redo some of these demonstrations.

For convenience, you need development tools. These can be downloaded here.

If you want more links on the Windows Phone development, I recommend this article from David.

1 - 10Suivante
 

 À propos de ce blog

 
À propos de ce blog
Bienvenue dans les blogs SharePoint. Utilisez cet espace pour fournir un message bref concernant ce blog ou ses auteurs. Pour modifier ce contenu, cliquez sur « Modifier la page » dans le menu « Actions du site ».