Benutzer mit den meisten Antworten
TreeNodeCollection ableiten

Frage
-
Hi,
ich habe mir eine ExtendedTreeView und eine ExtendedTreeNode Klasse geschrieben. Diese erben von System.Windows.Forms.TreeView bzw. System.Windows.Forms.TreeNode.
Nun hat die TreeView Klasse ein Property "Nodes" vom Typ TreeNodeCollection. Jedoch möchte ich an dieser Stelle direkt den Zugriff auf ExtendedTreeNodes ermöglichen ohne dass der Anwender dieses Controls einen Cast durchführen muss.
Deshalb dachte ich mir ich schreibe eine ExtendedTreeNodeCollection Klasse, welche von TreeNodeCollection erbt. Das Problem: TreeNodeCollection hat keinen Constructor. Also kann ich davon auch nicht ableiten, richtig?
Deshalb dachte ich mir ich lasse das erben von TreeNodeCollection weg und implementiere dafür (wie auch die TreeNodeCollection Klasse) die Interfaces ICollection, IList und IEnumerable. Das Problem: Ich kann in der ExtendedTreeView Klasse das Nodes Property nicht überschreiben, da die Datentypen nicht passen.
Habe dann zuletzt versucht das Nodes Property zu verstecken und dafür ein anderes Property zu schreiben (beispielsweise ExtendedNodes), welche dann die ExtendedNodesCollection liefert. Das funktioniert aber auch nicht da ich Nodes (anscheinend) nicht überschreiben darf...
Hat jemand irgendeine Idee wie ich das ganze lösen könnte?
Gruß
NbgSingh
Antworten
-
Hallo N.,
Du möchtest also in etwa diesen Code schreiben können:
TreeNodeEx nodeEx1 = new TreeNodeEx("Node1"); TreeNodeEx nodeEx2 = new TreeNodeEx("Node2"); treeViewEx1.Nodes.AddRange(new TreeNodeEx[] { nodeEx1, nodeEx2 }); TreeNodeCollectionEx nodes = treeViewEx1.Nodes; // kein Casten etc. notwendig
Dazu mußt Du den Zugriff auf TreeView.Nodes so wrappen, dass die ursprüngliche Collection nicht mehr nach außen sichtbar ist, Operationen wie Add(), Remove() etc. aber weiterhin an die zugrunde liegende Collection geleitet werden:
using System; using System.Collections.Generic; using System.Windows.Forms; using System.Runtime.Serialization; namespace WindowsFormsApplication1 { class TreeViewEx : TreeView { TreeNodeCollectionEx _collection; public TreeViewEx() { _collection = new TreeNodeCollectionEx(base.Nodes); } // Wir "verstecken" die ursprüngliche Implementation public new TreeNodeCollectionEx Nodes { // und geben unsere TreeNodeCollectionEx zurück get { return _collection; } } } // Hier könnten wir zusätzliche Methoden, Eigenschaften etc. implementieren class TreeNodeEx : TreeNode { public TreeNodeEx() { } public TreeNodeEx(string text) : base(text) { } public TreeNodeEx(string text, TreeNode[] children) : base(text, children) { } public TreeNodeEx(string text, int imageIndex, int selectedImageIndex) : base(text, imageIndex, selectedImageIndex) { } public TreeNodeEx(string text, int imageIndex, int selectedImageIndex, TreeNode[] children) : base(text, imageIndex, selectedImageIndex, children) { } protected TreeNodeEx(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext context) : base(serializationInfo, context) { } } // Und das ist unser Ersatz für die TreeNodeCollection class TreeNodeCollectionEx : ICollection<TreeNodeEx> { TreeNodeCollection _baseCollection; public TreeNodeCollectionEx(TreeNodeCollection collection) { _baseCollection = collection; foreach(TreeNode node in collection) { TreeNodeEx nodeEx = node as TreeNodeEx; if(nodeEx != null) Add(nodeEx); } } public void AddRange(TreeNodeEx[] items) { _baseCollection.AddRange(items); } #region ICollection<TreeNodeEx> Member public void Add(TreeNodeEx item) { _baseCollection.Add(item); } public void Clear() { _baseCollection.Clear(); } public bool Contains(TreeNodeEx item) { return _baseCollection.Contains(item); } public void CopyTo(TreeNodeEx[] array, int arrayIndex) { _baseCollection.CopyTo(array, arrayIndex); } public int Count { get { return _baseCollection.Count; } } public bool IsReadOnly { get { return _baseCollection.IsReadOnly; } } public bool Remove(TreeNodeEx item) { _baseCollection.Remove(item); return true; } #endregion #region IEnumerable<TreeNodeEx> Member public IEnumerator<TreeNodeEx> GetEnumerator() { return (IEnumerator<TreeNodeEx>)_baseCollection.GetEnumerator(); } #endregion #region IEnumerable Member System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return _baseCollection.GetEnumerator(); } #endregion } }
Natürlich ist der Beispiel-Code nur als Startpunkt zu verstehen.Gruß
Marcel- Als Antwort markiert NbgSingh Freitag, 12. August 2011 22:59
Alle Antworten
-
Hallo Nb,
folgendes erklärt dazu ein paar Dinge:
[Inheriting or overriding a class within a class... why not?]
http://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/b1d575d3-9028-4946-a8dd-2e89316f51c3/
ciao Frank -
Hallo N.,
Du möchtest also in etwa diesen Code schreiben können:
TreeNodeEx nodeEx1 = new TreeNodeEx("Node1"); TreeNodeEx nodeEx2 = new TreeNodeEx("Node2"); treeViewEx1.Nodes.AddRange(new TreeNodeEx[] { nodeEx1, nodeEx2 }); TreeNodeCollectionEx nodes = treeViewEx1.Nodes; // kein Casten etc. notwendig
Dazu mußt Du den Zugriff auf TreeView.Nodes so wrappen, dass die ursprüngliche Collection nicht mehr nach außen sichtbar ist, Operationen wie Add(), Remove() etc. aber weiterhin an die zugrunde liegende Collection geleitet werden:
using System; using System.Collections.Generic; using System.Windows.Forms; using System.Runtime.Serialization; namespace WindowsFormsApplication1 { class TreeViewEx : TreeView { TreeNodeCollectionEx _collection; public TreeViewEx() { _collection = new TreeNodeCollectionEx(base.Nodes); } // Wir "verstecken" die ursprüngliche Implementation public new TreeNodeCollectionEx Nodes { // und geben unsere TreeNodeCollectionEx zurück get { return _collection; } } } // Hier könnten wir zusätzliche Methoden, Eigenschaften etc. implementieren class TreeNodeEx : TreeNode { public TreeNodeEx() { } public TreeNodeEx(string text) : base(text) { } public TreeNodeEx(string text, TreeNode[] children) : base(text, children) { } public TreeNodeEx(string text, int imageIndex, int selectedImageIndex) : base(text, imageIndex, selectedImageIndex) { } public TreeNodeEx(string text, int imageIndex, int selectedImageIndex, TreeNode[] children) : base(text, imageIndex, selectedImageIndex, children) { } protected TreeNodeEx(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext context) : base(serializationInfo, context) { } } // Und das ist unser Ersatz für die TreeNodeCollection class TreeNodeCollectionEx : ICollection<TreeNodeEx> { TreeNodeCollection _baseCollection; public TreeNodeCollectionEx(TreeNodeCollection collection) { _baseCollection = collection; foreach(TreeNode node in collection) { TreeNodeEx nodeEx = node as TreeNodeEx; if(nodeEx != null) Add(nodeEx); } } public void AddRange(TreeNodeEx[] items) { _baseCollection.AddRange(items); } #region ICollection<TreeNodeEx> Member public void Add(TreeNodeEx item) { _baseCollection.Add(item); } public void Clear() { _baseCollection.Clear(); } public bool Contains(TreeNodeEx item) { return _baseCollection.Contains(item); } public void CopyTo(TreeNodeEx[] array, int arrayIndex) { _baseCollection.CopyTo(array, arrayIndex); } public int Count { get { return _baseCollection.Count; } } public bool IsReadOnly { get { return _baseCollection.IsReadOnly; } } public bool Remove(TreeNodeEx item) { _baseCollection.Remove(item); return true; } #endregion #region IEnumerable<TreeNodeEx> Member public IEnumerator<TreeNodeEx> GetEnumerator() { return (IEnumerator<TreeNodeEx>)_baseCollection.GetEnumerator(); } #endregion #region IEnumerable Member System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return _baseCollection.GetEnumerator(); } #endregion } }
Natürlich ist der Beispiel-Code nur als Startpunkt zu verstehen.Gruß
Marcel- Als Antwort markiert NbgSingh Freitag, 12. August 2011 22:59
-
Hallo NB,
in meinem Link hast Du erfahren, warum das recht aufwendig gewrappt werden muss.
Hier auch Beispiele für solche Implementierungen:
http://www.koders.com/csharp/fid17DC01E4124C334CE19190F5F0B6FCCAE8475B7C.aspx?s=treeview
http://www.koders.com/csharp/fidBDF082855EA51AE834BBA3E02D07EE293C6E43A2.aspx?s=control
http://www.koders.com/csharp/fid93C99BC8B6649FD8A914C950843D2AA58335E512.aspx?s=treeview
ciao Frank