mercredi 30 juillet 2008

PoshBoard, seconde vidéo : PowerShell génère des Datagrids Silverlight

English version here

Voici une nouvelle vidéo de Poshboard, mon projet open source de portail IT. Dans cette vidéo, vous découvrirez les dernières nouveautés arrivant avec la version 0.3 (disponible ici sur codeplex prochainement) :

Lancez la lecture, cliquez sur HD, puis passez en plein écran (ou téléchargez là ici), spécialement car ma capture vidéo est légèrement partie en vrille côté rescaling :-)


Poshboard Seconde video : Datagrid (Silverlight 2, AgDataGrid) et nouvelle GUI from pilosite on Vimeo.


Au programme ?

De nouveaux Widgets :


- Gestion des datagrid Silverlight 2 : générez les à partir d'un simple objet PowerShell
- Utilisation du contrôle AgDatagrid de developer Express, une excellente datagrid gratuite et open source en Silverlight bourrée de bonnes idées.
- La gestion de sortie standard PowerShell

Une nouvelle interface :


Cette version est basée sur la version 1.6.0 de Dropthings, voyez la en action et découvrez les nouveautés (design amélioré, gestion dynamique de la taille et position des colonnes...)

Un tutorial d'install arrive, expliquant :

- Comment installer le portail sur un serveur (pré-requis, configuration IIS, sécurité...)
- Comment jouer avec au moyen de Visual Studio 2008 et Web developper express 2008 SP1/ SQL 2008 CTP

Posez vos questions dans les commentaires, et n'hésitez pas à utiliser la gestion des issues/discussions sur le site de codeplex pour me permettre de faire évoluer au mieux le projet !

Bonne vidéo ;)

vendredi 25 juillet 2008

AgDatagrid et Silverlight Datagrid : comment créer dynamiquement une Datasource ?

English version available HERE

Le code source du projet est disponible ici.

Un exemple live juste en dessous !



Je travaille actuellement sur le composant AgDataGrid, un excellent contrôle Silverlight gratuit et open source de DevExpress (Démonstration complète ici). Bien entendu, mon but est d'implémenter celui-ci comme widget dans PowerShell Dashboard ;-)

J'ai rencontré un petit problème, qui est d'ailleurs valable pour le contrôle DataGrid standard de Silverlight 2, et plus généralement pour la génération dynamique d'objets typés en .NET :

Comment créer dynamiquement la Datagrid ?

AgDatagrid et la datagrid Silverlight 2 utilisent un objet de type IList pour construire la Datasource. Quand on utilise du code managé (C#/VB.NET...), vous devez créer une classe représentant vos données pour pouvoir construire cette IList :

   1: public class Person {   
   2:                 public string Name {   
   3:                      get;   
   4:                      set;   
   5:                 }   
   6:     
   7:                 public string City {   
   8:                      get;   
   9:                      set;   
  10:                 }   
  11:     
  12:                 public string State {   
  13:                      get;   
  14:                      set;   
  15:                 }   
  16:            }   
  17:     
  18: new Person() {   
  19: me = "Michael Jordan", City="Chicago", State="IL" },   
  20: new Person() {   
  21: me = "Kobe Bryant", City="Los Angeles", State="CA" },   
  22: new Person() {   
  23: me = "Shaquille O'Neil", City="Miami", State="FL" },   
  24: new Person() {   
  25: me = "Patrick Ewing", City="New York", State="NY" }    


  26:  



C'est impeccable quand vous connaissez votre source de données, mais comment faire quand vous avez du contenu dynamique (comme par exemple le retour d'un script PowerShell) ?

Je veux en effet utiliser la grid pour afficher mes données venant de PowerShell, je ne connais donc pas par avance le type des objets ni le nombre de colonnes...

Voici le point clé : je ne peux pas utiliser de classe statique pour définir mes données dans le contrôle Silverlight.

Game Over ?


Pas encore!

Nous avons deux stratégies à notre disposition pour arriver à notre résultat :

- Utiliser la programmation par langage dynamique avec Silverlight (Ironpython, IronRuby, JScript managé...) pour construire dynamiquement le contrôle ?

- Créer malgré tout dynamiquement la classe en code managé ?

Utiliser les langages dynamiques serait une solution idéale (et pour moi la meilleure à terme). Malheureusement, nous sommes encore au stade de la Beta côté siverlight et DSL, et il est aujourd'hui encore difficile de créer dynamiquement des contrôles Silverlight 2 Beta 2 dans ce contexte (pour le moment) car tout n'est pas encore figé dans le marbre :), je ne vais donc pas rentrer dans cette explication pour le moment (J'attends avec impatience quelques exemples de la part de l'équipe Silverlight sur ce sujet )

Alors, pouvons nous créer dynamiquement la classe dans notre code managé ?

Ma réponse est : OUI !

Comment générer des objets typés dynamiquement en .NET

Après quelques recherches (INTENSIVES est le mot juste), j'ai trouvé un post excellent de Vladimir Bodurov sous le thème : "How to generated dynamically typed objects in .NET" :

http://www.simple-talk.com/dotnet/.net-framework/dynamically-generating--typed-objects-in-.net/

Bingo ! Vladimir nous donne le code magique pour construire nos objets dynamiquement que nous pouvons simplement implémenter comme Datasource, sans coder de classe statique !

Ok, génial. Voyons maintenant comment j'ai utilisé ceci avec AgDatagrid (Vous pourrez très facilement convertir cet exemple avec le contrôle standard Datagrid de Silverlight 2, mais il n'est pas aussi classe et riche que le super contrôle de Devexpress :-) )

Allons-y messieurs dames, jetons un oeil dans le code !

Mon exemple est l'implémentation la plus basique possible afin de bien vous faire comprendre le principe

mon fichier Page.xaml est plutôt simple :

agdynamic2

J'ai posé 2 Textboxes (Une pour les noms de colonnes, une pour les données), un bouton pour construire la datagrid, et la datagrid elle-même. Nous pourrions récupérer les données de l'extérieur, mais ceci est un autre sujet, je souhaite rester volontairement simpliste.

Voici le code XAML de la page:



   1: <UserControl x:Class="AgDatagridDynamicData.Page"   
   2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    
   3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    
   4:     xmlns:ag="clr-namespace:DevExpress.Windows.Controls;assembly=DevExpress.AgDataGrid.v8.2"   
   5:     xmlns:local="clr-namespace:AgDatagridDynamicData"   
   6:     Width="800" Height="600">   
   7:     <Grid x:Name="LayoutRoot" Background="black">   
   8:         <Grid>   
   9:             <Grid.RowDefinitions>   
  10:                 <RowDefinition Height="Auto"></RowDefinition>   
  11:                 <RowDefinition Height="Auto"></RowDefinition>   
  12:                 <RowDefinition Height="Auto"></RowDefinition>   
  13:                 <RowDefinition Height="Auto"></RowDefinition>   
  14:             </Grid.RowDefinitions>   
  15:             <Grid.ColumnDefinitions>   
  16:                 <ColumnDefinition Width="Auto"/>   
  17:                 <ColumnDefinition Width="Auto"/>   
  18:             </Grid.ColumnDefinitions>   
  19:             <TextBlock Width="Auto" Grid.Row="0" Grid.Column="0" Text="Columns (Parse with ';'):" />                   
  20:             <TextBox x:Name="ColumnsData" Background="blackSmoke" Width="500" Grid.Row="0" Grid.Column="1" Text="Column1;Column2;Column3"></TextBox>   
  21:             <TextBlock Width="Auto" Grid.Row="1" Grid.Column="0" Text="Data (Parse Row with '*', cells with ';' :" />
  22:             <TextBox x:Name="CellsData" Background="blackSmoke" Width="500" Grid.Row="1" Grid.Column="1" Text="DataA1;DataA2;DataA3*DataB1;DataB2;DataB3"></TextBox>     
  23:             <Button Click="Button_Click" Grid.Row="2" Grid.ColumnSpan="2" Content="Generate AgDataGrid"></Button>   
  24:             <ag:AgDataGrid Width="800" Height="400" Grid.Row="3" Grid.ColumnSpan="2" AutoGenerateColumns="True" x:Name="mygrid">   
  25:                 </ag:AgDataGrid>   
  26:         </Grid>           
  27:     </Grid>   
  28: </UserControl>



Toute la subtilité est dans la page.xaml.cs, regardons la de plus près.

J'utilise seulement les données des textboxes du contrôle Silverlight (Vous verrez dans la version Widget pour PoshBoard comment vous y prendre pour aller chercher les données à l'extérieur)

J'utilise simplement du parsage de string pour construire ma Datagrid :
  • Les colonnes sont splittées avec un ";"
  • Les données sont splittées avec "*" pour chaque ligne, et dans ces lignes les cellules sont splittées avec un ";"
Bien sûr, il serait plus sage de plutôt utiliser XML pour définir ces données, mais restons dans notre optique de simplicité.

Colonne :

Column1;Column2;Column3

Données :

DataA1;DataA2;DataA3*DataB1;DataB2;DataB3*DataC1;DataC2;DataC3

Première chose, Je met directement la classe DataSourceCreator de Vladimir dans le namespace de mon contrôle, sans toucher à rien (C'est ce que j'apelle du code magique)

agdynamic1


Après avoir insérer le code pour appelé les différentes libs nécessaire à la classe de Vladimir(System.Reflection, etc...), définissons le code principal de ma page :

Voyons notre classe principale (UserControl ) :



   1: public partial class Page : UserControl   
   2:     {   
   3:     string Columns;   
   4:     string Data;   
   5:         public Page()   
   6:         {   
   7:             InitializeComponent();               
   8:         }   
   9:     
  10:         private void Button_Click(object sender, RoutedEventArgs e)   
  11:         {   
  12:     
  13:             mygrid.Columns.Clear();   
  14:             // Adding Columns to the AgDatagrid   
  15:             // With Column type added in the Columns string    
  16:             // we could use a Type checker and setting Column Type   
  17:             // from code behind :    
  18:             // mygrid.Columns.Add(new AgDataGridTextColumn() { FieldName = SingleColumn});     
  19:             Columns = ColumnsData.Text;   
  20:             Data = CellsData.Text;   
  21:             foreach (string SingleColumn in Columns.Split(';'))   
  22:             {              
  23:                 mygrid.AddColumn(SingleColumn);
  24:             }
  25:  
  26:             // Here we set the DataSource with a direct call to the function of
  27:             // Vladimir            
  28:             mygrid.DataSource = GenerateData().ToDataSource();        
  29:         }

Que fait-on ici ?

Rien de spécial dans la fonction Public Page() : J'initialise le composant (c'est le code par défaut)

Tout est dans la fonction "Button_Click" :



   1: private void Button_Click(object sender, RoutedEventArgs e)   
   2: {
   3:  
   4:     mygrid.Columns.Clear();
   5:     // Adding Columns to the AgDatagrid
   6:     // With Column type added in the Columns string 
   7:     // we could use a Type checker and setting Column Type
   8:     // from code behind : 
   9:     // mygrid.Columns.Add(new AgDataGridTextColumn() { FieldName = SingleColumn});  
  10:     Columns = ColumnsData.Text;
  11:     Data = CellsData.Text;
  12:     foreach (string SingleColumn in Columns.Split(';'))
  13:     {                
  14:         mygrid.AddColumn(SingleColumn);
  15:     }
  16:  
  17:     // Here we set the DataSource with a direct call to the function of
  18:     // Vladimir            
  19:     mygrid.DataSource = GenerateData().ToDataSource();        
  20: }


Premièrement, je vide la datagrid (sans ça, ma fonction ferait de l'ajout, pas de la création from scratch à chaque click)

Ensuite nous récupérons les données des 2 textbox, puis nous allons créer les colonnes :


   1: foreach (string SingleColumn in Columns.Split(';'))
   2: {
   3:     mygrid.Columns.Add(new AgDataGridTextColumn() { FieldName = SingleColumn });
   4: }


Je génère ici que des colonnes de type "texte". Nous pourrions très facilement définir le type dans la chaine de caractère pour implémenter tout ce que propose AgDatagrid, mais encore une fois je suis resté basique (La faute peut-être à mon pot Chez Octo d'hier) :

Ensuite, je défini la Datasource:


   1: mygrid.DataSource = GenerateData().ToDataSource(); 


Nous faisons appelle à la fonction GenerateDate dans la classe (J'ai juste récupéré l'exemple de Vladimir Que j'ai réadapté) :



   1: public IEnumerable<IDictionary> GenerateData()
   2: {
   3:     string[] dataSplit = Data.Split('*');
   4:     int RowNumber = dataSplit.Count();
   5:     string[] ColumnSplit = Columns.Split(';');
   6:     int ColumnNumber = ColumnSplit.Count();
   7:     for (var i = 0; i < RowNumber; i++)
   8:     {
   9:         string[] cellData = dataSplit[i].Split(';');
  10:         var dict = new Dictionary<string, object>();
  11:         for (var j = 0; j < ColumnNumber; j++)
  12:         {
  13:             dict[ColumnSplit[j]] = cellData[j];
  14:         }
  15:        yield return dict;                
  16:     }             
  17: }



tout ce passe dans ce code précis. comment cela fonctionne-t-il donc ? On déclare un dictionnaire et nous l'alimentons avec des séries Clés/valeurs :

Le clé est le nom de la colonne visée , value est le contenu de la cellule à ajouter. Comme vous le voyez on défini avec cette méthode dynamiquement le nom de colonne visée à partir de la référence de notre string Column :

dict[ColulmnSplit[J]] = ...

c'est ce procédé qui nous évite d'avoir a définir la classe, c'e'st tout simplement excellent.

Et c'est tout !

Comme vous pouvez le constater, il est très facile d'alimenter dynamiquemenet une Datasource avec ce procédé.

Pour aller plus loin, nous pourrions utiliser un format XML pour la récupération des données, choisir un type de données pour les colonnes en fonction du type fourni en entrée.... les possibilité sont infinies !

Un grand merci à Azret et l'équipe support de DevExpress pour leur aide réactive, et merci à Vladimir Bodurov pour son superbe exemple de code que je vous invite à consulter pour comprendre tout le mécanisme !

Des questions ? les commentaires sont à votre disposition !

AMUSEZ VOUS BIEN AVEC SILVERLIGHT ET AGDATAGRID !

vendredi 18 juillet 2008

PoshBoard présenté dans le PowerShell Podcast 33

Dans le dernier numéro de PowerShell Podcast (excellent podcast sur PowerShell que je vous invite à découvrir si vous n'avez jamais pratiqué), Jonathan Walz et Hal Rottenberg parlent (entre autre!) de mon site et présente le projet PoshBoard.

Merci à eux de l'intérêt qu'il porte à mon travail, ça me fait réellement plaisir ;), vous pouvez retrouver ce podcast sur leur site PowerScripting

jeudi 10 juillet 2008

Poshboard dispo en preview !

Suite à plusieurs demande pour tester le portail, j'ai mis une pré-version disponible dès à présent sur codeplex en cliquant ICI ou rendez vous sur http://www.codeplex.com/poshboard

Amusez-vous bien et n'hésitez pas à me poser vos questions !

samedi 5 juillet 2008

PowerShell Dashboard : ASP.NET, Silverlight et PowerShell dans un shaker !

English Version available here

Mis-à-Jour : le code source d'une préversion est maintenant disponible sur CodePlex, cliquez ICI ou rendez vous sur http://www.codeplex.com/poshboard

Je vous propose une petite vidéo de présentation de mon projet "PowerShell Dashboard" (PoshBoard pour les intimes) actuellement en développement et prochainement disponible via la forge Octo.

Il s'agit d'un projet open source dont l'objectif est de mettre à disposition un portail très modulaire basé sur PowerShell. L'idée est de reprendre le concept des interfaces tels que igoogle, PageFlakes ou Netvibes, mais orienté admin système.

Pourquoi ? pour pouvoir créer très facilement des dashboards infrastructure sans avoir à coder en ASP.NET / Ajax ou autre : la seule compétence requise est le scripting.

Ce projet s'appuie sur Dropthings, le portail ASP.NET / AJAX d'Omar AL Zabir, réorienté en intranet. Pour cette première démonstration et un premier widget, je m'appuie sur le rendu de graphique (Colonnes, camembert...) grâce à l'excellente librairie de graphique Silverlight VISIFIRE, elle aussi gratuite et open source.

Cette première démo présente le concept général du portail que je vous mettrai prochainement à disposition en téléchargement libre. Viendra ensuite d'autres composants et innovations pour vous apporter toujours plus de fun dans l'utilisation de PowerShell ! :)

Trève de blabla, voici la vidéo de démonstration :



PowerShell Dashboard from pilosite on Vimeo.

Cette vidéo pour votre confort étant au format HD 1280x720,Je vous invite très fortement a cliquer sur le l'icône HD (après avoir lancé la lecture) afin de voir cette présentation en haute résolution (Mettez ensuite la vidéo en plein écran pour avoir la résolution native optimale). Vous pouvez aussi simplement cliquer ici et passer en plein écran. Vous pourrez avec ce lient télécharger la vidéo au format wmv.

Des questions ? n'hésitez pas à poster un commentaire ou me joindre par mail en cliquant ici

Vous souhaitez intégrer en avant première ce type de technologie dans votre entreprise, découvrir les autres composants en cours d'élaboration, vous former ou former vos équipes sur PowerShell ? alors contactez moi :

je m'occupe au sein de la société OCTO TECHNOLOGY d'une offre infrastructure dédiée à ces thématiques, et c'est avec grand plaisir que nous pouvons étudier avec vous vos besoins concrets et vous apporter le conseil et l'aide à l'intégration sur tout projets de développement orienté infrastructure tels que ce portail, et bien plus.

Demandez plus d'informations en passant par la rubrique contact de notre site internet !