Thursday, October 30, 2008

Utilisation de PropertyGrid avec des elements de TreeView.

Le framework Dotnet possede des widgets tres interressantes.
Comme les TreeView s certe assez classique.
TreeView Class (System.Windows.Forms)
Mais aussi une widget tres sympa PropertyGrid
Getting the Most Out of the .NET Framework PropertyGrid Control



Pour afficher les proprietés d'un objet dans la PropetyGrid, le code est simplicime.

propertyGrid1.SelectedObject = yourObject;

Il faut cependant que yourObject derive de Object.

Voila mon problème est le suivant, j'ai un treeView sur des element Html provenant
des elements du document html telechargé.
Je remplit recursivement mon treeView avec les elements Html.

private void FillTree(HtmlElement hElmFather, TreeNodeHtmlElm t)
{
foreach (HtmlElement hElm in hElmFather.Children)
{
t.Nodes.Add(hElm.InnerText);
if (hElm.Children.Count > 0)
{
FillTree(hElm, node);
}
}
}


Methode recursive qui marche tres bien , j'ai ainsi un TreeView avec les elements hierarchiques de mon document html.
et je voudrais afficher les proprietés de ces elements dans la ProprytyGrid.

Lorsque je selectionne un element du TreeView alors j'ai des un Event :

private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)


Mais mon treeView1.SelectedNode élement selectionné ne contient pas les proprietés de mes
element Html , mais de la node du TreeView.

Voici la solution trouvée et je pense la meilleur enfin j'espere.

Il faut dérivé la class TreeNode en TreeNodeHtmlElm :


public class TreeNodeHtmlElm : TreeNode
{
public HtmlElement mHtmlElement;

public TreeNodeHtmlElm(HtmlElement elm) : base()
{
mHtmlElement = elm;
Text = elm.OuterText;
}
};

Apres au lieu d'ajouter un TreeNode , vous ajoutez un TreeNodeHtmlElm.
Cependant la construction pour que la compilation s'effectue bien, est un peu differente
ce qui reste un mystere pour moi.

Il faut faire ainsi :

private void FillTree(HtmlElement hElmFather, TreeNodeHtmlElm t)
{
foreach (HtmlElement hElm in hElmFather.Children)
{
TreeNodeHtmlElm node = new TreeNodeHtmlElm(hElm);
t.Nodes.Add((TreeNode)node);
if (hElm.Children.Count > 0)
{
FillTree(hElm, node);
}
}
}

On est obligé de passer pas une variable temporaire sinon cela ne compile pas.

Et apres faites comme ceci pour voir les proprietés dans l'objet dans la propertyGrid:

TreeNodeHtmlElm tn = (TreeNodeHtmlElm)(treeView1.SelectedNode);
propertyGrid1.SelectedObject = tn.mHtmlElement;

J'essayerais de faire un article sur codeproject pour mieux mettre en oeuvre cela.

Monday, October 27, 2008

Article sur Code Project : a Graphical Rectangle Resizable

Je voulais une zone rectangulaire de sélection dans une zone de Dessin pour un programme en c#.
Je l'ai fait est je me suis dis qu'il fallait que je partage ce petit bout de code avec d'autre.

L'idee est d'afficher un rectangle avec des poignées pour le redimensionner comme on veux.
Add Image
Voici le lien :
a Graphical Rectangle Resizable

Et quelle fut ma surprise quand j'ai vu que Ilíon a mis un commentaire.
Il m'a félicité, et aimerais que le rectangle ne dépasse pas la zone.

Donc j'ai fait cela de la maniere suivante:
A la fin des modifications alors je teste si le rectangle est toujours dans la zone.
Si non soit on bloque la valeur ou je reduis la hauteur et la largeur du rectangle.

public bool allowDeformingDuringMovement=true ;

Si l'on bouge le rectangle contre les bords alors il s'applatit ( la hauteur ou la largeur diminue suivant le sens ).


if (rect.X + rect.Width > mPictureBox.Width)
{
rect.Width = mPictureBox.Width - rect.X - 1; // -1 to be still show
if (allowDeformingDuringMovement == false)
{
mIsClick = false; // on arrete les mouvements
}
}
if (rect.Y + rect.Height > mPictureBox.Height)
{
rect.Height = mPictureBox.Height - rect.Y - 1;// -1 to be still show
if (allowDeformingDuringMovement == false)
{
mIsClick = false; // on arrete les mouvement.
}
}





Sunday, October 26, 2008

J'ai utilisé : TemplateMaschine c#

J'ai utilisé : TemplateMaschine

Utiliser pour generer des pages web :

La template :

Bon je vais vous decrire brievement :
Ma page html doit contenir une entete declarative des variables utilisés :

<%@ Import NameSpace="System.Collections.Generic" %&rt;
<%@ Argument Name="elm" Type="List" %>
<%@ Argument Name="content" Type="String" %>



J'importe le namespace pour utilisé les listes ( NET 2 )
Et j'ai une liste de pages en liens ( home , galllery , product , contact .... )
Et aussi un contenu html

Voici l'integration dans la page web.
...
[html]
....

<% int n = 0; foreach(string attr in elm) { %>

[html]

<%=attr%>

[html]
.....
<% } %>
..

et pour la variable contenu :

[html]
<%=content%>
[html]

[html] : reprensente de code html difficilement integrable ici.
Le code est placé ente <% et %> ( comme en ASP , et peut etre JSP ) ( PHP etant et co )
Ici pas de echo "content" ( php ) , mais <%=content%> pour afficher la valeur string de la variable

J'ai un mauvais souvenir des jsp car ils modifé la page en l'incluant dans du code ...
et le compile dans un fichier temporaire ...

Bon la c'est un peu la meme chose je crois , on profite des fonctionnalités de la compilation dynamique de c#/dotnet ( donet ecrit et compile apres le fichier dans un repertoire temporaire)

Evaluate C# Code (Eval Function)
icc.CompileAssemblyFromSource
Le source c#:

il faut importer
using TemplateMaschine;

L'appel a template se faire alors ainsi :

Template myTemplate = new Template(GetTemplatePage());

myTemplate.Generate(
new object[] {
elmPages, /// <- ceci est une List
page.HtmlContent,
}
, "generated\\" + page.Name + ".html"
);


Moi je suis content car ca marche plus bien , bravo a l'auteur de ces classes de template
me permettant d'avoir l'ensemble de la puissance de c#

Cependant pour des templates Html, il faut patcher TemplateMaschine.cs.
Il faut modifier la methode private TokenInfo NextToken() pour que les commentaires et les scripts ne soient pas pris en compte.