2009-09-17 7 views
2

J'ai une classe qui hérite de TreeNode, appelée ExtendedTreeNode. Ajouter un objet de ce type à l'arborescence n'est pas un problème. Mais comment puis-je récupérer l'objet de l'arborescence?Comment hériter de la classe treenode?

J'ai essayé:

TreeNode node = tvManual.Find("path/to/node"); // tvManual is a treeview 

return ((ExtendedTreeNode)node).Property; 

Mais cela ne fonctionne pas. Je reçois cette erreur: Impossible de convertir l'objet de type 'System.Web.UI.WebControls.TreeNode' en type 'PCK_Web_new.Classes.ExtendedTreeNode'.

Que dois-je faire pour que cela fonctionne?

------------ SOLUTION -----------------

[Modifier] Ma classe TreeNode personnalisée ressemble à ceci:

public class ExtendedTreeNode : TreeNode 
{ 
    private int _UniqueId; 

    public int UniqueId 
    { 
     set { _UniqueId = value; } 
     get { return _UniqueId; } 
    } 
    public ExtendedTreeNode() 
    { 
    } 
} 

Et ainsi ajouter des nœuds à mon TreeView:

ExtendedTreeNode TN2 = new ExtendedTreeNode(); 

TN2.Text = "<span class='Node'>" + doc.Title + "</span>"; 
TN2.Value = doc.ID.ToString(); 
TN2.NavigateUrl = "ViewDocument.aspx?id=" + doc.ID + "&doc=general&p=" + parent; 
TN2.ImageUrl = "Graphics/algDoc.png"; 
TN2.ToolTip = doc.Title; 
TN2.UniqueId = counter; 

tvManual.FindNode(parent).ChildNodes.Add(TN2); 

Et cette façon, je récupérer mon objet ExtendedTreeNode:

TreeNode node = tvManual.Find("path/to/node"); 
ExtendedTreeNode extNode = node as ExtendedTreeNode; 
return extNode.UniqueId; 

J'utilise .NET 3.5 SP1

+0

Est-ce que tous les nœuds ajoutés sont de type ExtendedTreeNode? ou ajoutez-vous également des objets TreeNode réguliers? Peut-être pourriez-vous montrer comment vous les ajoutez à TreeView. – SwDevMan81

+0

Oui, tous les nœuds doivent être de type ExtendedTreeNode – Martijn

+0

D'une manière ou d'une autre (au moins dans ASP.NET) le 'TreeView' convertit le' TreeNode' hérité en 'TreeNode's. J'ai essayé de surcharger 'Clone', mais cela n'a pas aidé. Mes 'TreeNode' étendus sont encore retournés en réguliers d'une manière ou d'une autre. Je suppose que je devrais utiliser un réflecteur ou quelque chose pour voir ce qui se passe. –

Répondre

1

Vous pouvez essayer ce qui suit pour obtenir tous les nœuds sous votre parent:

TreeNode[] parentNode = treeView1.Nodes.Find (parentid, true); 
foreach(TreeNode node in parentNode) 
{ 
    ExtendedTreeNode ext_tree_node = node as ExtendedTreeNode; 
    if(ext_tree_node != null) 
    { 
     // Do your work 
    } 
} 
+0

Lorsque je fais ExtendedTreeNode énode = node as ExtendedTreeNode; L'énode est toujours nulle. Comment venir? – Martijn

+0

lors de l'utilisation de la fonction de diffusion (appelée diffusion en toute sécurité), si la diffusion échoue, l'objet est défini sur null –

+0

Comment puis-je faire en sorte que cela fonctionne? Ou qu'est-ce qui ne va pas? – Martijn

0

Je suppose que vous créez les nœuds comme ExtendedTreeNode s.

J'ai remarqué que les contrôles XxxView (ListView, TreeView, DataGridView) ont tendance à cloner des choses de manière inattendue. Avez-vous mis en œuvre ICloneable.Clone()?

Cela peut fonctionner; TreeNode implémente Clone() virtuellement.

Je trouve plus facile, mais de mettre en œuvre les propriétés étendues en utilisant la propriété Tag du treenode:

TreeNode node = tvManual.Find("path/to/node"); 
return node.Tag as ExtendedTreeNode; 

Je recommande fortement l'utilisation Clone(); c'est un motif fragile. Utilisez la propriété Tag:

class ExtendedInfo 
{ 
    string NavigateUrl; 
    string ImageUrl; 
    int UniqueId; 

    // other custom properties go here 
} 

// ... 

void CreateTreeNode() 
{ 
    TreeNode TN = new TreeNode(); 

    string parent = "parent";  

    TN.Text = "<span class='Node'>" + doc.Title + "</span>"; 
    TN.Value = doc.ID.ToString(); 
    TN.ToolTip = doc.Title; 

    ExtendedInfo extInfo = new ExtendedInfo; 
    extInfo.NavigateUrl = "ViewDocument.aspx?id=" + doc.ID + "&doc=general&p=" + parent; 
    extInfo.ImageUrl = "Graphics/algDoc.png"; 
    extInfo.UniqueId = counter; 

    TN.Tag = extInfo; 
} 

// ... 

ExtendedInfo GetExtendedInfo (TreeNode node) 
{ 
    return node.Tag as ExtendedInfo; 
} 
+0

Non, je n'ai pas implémenté ICloneble.Clone() Dois-je le faire? Si c'est le cas, comment? – Martijn

+0

La propriété Tag du TreeNode n'existe pas? – Martijn

+0

object TreeNode.Tag existe dans Windows Forms. Pas sûr de ASP.NET, mais pourquoi pas? – XXXXX

1

Je trouve un exemple Microsoft pour savoir comment mettre en œuvre un ASP.NET TreeView avec des balises here.

Quelques étapes importantes qui sont nécessaires en plus que le sous-classement TreeNode et en ajoutant une propriété Tag sont:

Vous devez sous-classe TreeView et remplacer la méthode CreateNode:

public sealed class TaggedTreeView : TreeView { 
    protected override TreeNode CreateNode() { 
     return new TaggedTreeNode(this, false); 
    } 
} 

Cela empêche le TreeView d'écraser votre nouveau nœuds avec TreeNode s au lieu de votre type de nœud étendu.

Vous aurez besoin de ce constructeur particulier. (Il semble fonctionner à l'aide du constructeur par défaut, aussi, mais il y a une bonne chance il y a une bonne raison pour laquelle ils ont utilisé celui-ci.)

public sealed class TaggedTreeNode : TreeNode { 
    object _Tag; 

    public object Tag { get { return _Tag; } set { _Tag = value; } } 

    ... 

    protected internal TaggedTreeNode(TreeView owner, bool isRoot) 
    : base(owner, isRoot) { 
    } 

Pour utiliser la TreeView étendue, vous aurez besoin d'une ligne Register comme le suivant dans votre balisage pour importer le type:

<%@ Register TagPrefix="asp" Namespace="MyNamespace" Assembly="MyAssembly" %> 

... 

<asp:TaggedTreeView ID="taggedTreeView" runat="server" /> 

Vous devez également remplacer LoadViewState et SaveViewState dans votre classe TreeNode héritée:

public sealed class TaggedTreeNode : TreeNode { 

    ... 

    protected override void LoadViewState(object state) { 
     var arrState = (object[])state; 
     _Tag = arrState[0]; 
     base.LoadViewState(arrState[1]); 
    } 

    protected override object SaveViewState() { 
     var arrState = new object[2]; 
     arrState[1] = base.SaveViewState(); 
     arrState[0] = _Tag; 
     return arrState; 
    } 

Cela permet au TreeView de préserver la valeur de vos propriétés Tag entre les publications.

+0

Pourquoi pas simplement un objet public? Tag {get; set;}? – dlchambers

+0

@dlchambers Bien sûr, je ne faisais que copier l'implémentation de MS. peut réellement étendre 'TreeNode' comme vous le souhaitez; l'ajout d'une «étiquette» est juste une possibilité. –

Questions connexes