سؤال

أولاً ، لدينا رمز سبحانه وتعالى!

List nodes = new List();
TreeNode Temp = new TreeNode();

TreeNodeCollection nodeList = treeViewTab4DirectoryTree.Nodes;

while (nodeList.Count != 0)
{
    Temp = nodeList[0];

    while (Temp.FirstNode != null)
    {
        Temp = Temp.FirstNode;
    }

    if (!nodes.Contains(Temp.FullPath))
    {
        nodes.Add(Temp.Text);
    }

    nodeList.Remove(Temp);
}

الآن المشكلة: لقد كتبت الرمز أعلاه بقصد إنشاء قائمة تحتوي على النص من جميع العقد في الشجرة. هذا يعمل تماما. المشكلة التي أواجهها هي عندما أقوم بإزالة العقد من المتغير الذي يتم إزالته أيضًا من القائمة الفعلية. سيكون السؤال هو كيف يمكنني عمل نسخة من قائمة العقد حتى أتمكن من اللعب معهم دون العبث بالقائمة الفعلية. كيف أقوم بعمل نسخة منه دون مجرد الإشارة إليها؟ أي مساعدة سوف تكون محل تقدير كبير!

هل كانت مفيدة؟

المحلول

تنشأ مشكلتك لأن "NodeList" هي إشارة إلى TreeViewTab4DirectoryTree.nodes ، بدلاً من نسخة منه.

يعتمد الحل بالكامل على نوع treenodecollection الذي تستخدمه (winforms ، asp.net ، شيء آخر؟) ، حيث ستحتاج إلى البحث عن طريقة .copy () ، .clone () ، .toRray () أو مشابه لاتخاذ أ ينسخ من محتويات المجموعة ، بدلاً من الإشارة إلى المجموعة الحالية.

إذا ، على سبيل المثال ، كنت تستخدم ASP.NET وبالتالي system.web.ui.webcontrols.treeNodecollection, ، يمكنك استخدام طريقة .copyto بطريقة مشابهة لهذا:

TreeNode[] x = null;
treeViewTab4DirectoryTree.Nodes.CopyTo(x, 0);

نصائح أخرى

تم تحديثه لإظهار النهج القائم على المكدس:

List<String> result = new List<String>();
Stack<IEnumerator> nodeColls = new Stack<IEnumerator>();
IEnumerator nodes = treeViewTab4DirectoryTree.Nodes.GetEnumerator();

nodeColls.Push(null);

while (nodes != null)
{
    while (nodes.MoveNext())
    {
        result.add(nodes.Current.FullPath);
        if (nodes.Current.FirstNode != null)
        {
            nodeColls.Push(nodes);
            nodes = nodes.Current.Nodes.GetEnumerator();
        }
    }

    nodes = nodeColls.Pop();
}

لا يعمل الرمز أدناه كما ذكر في التعليقات ، لأنه لا يعبر الشجرة بأكملها ، ولكنها تأخذ فقط عقدة الورقة الأولى لكل فرع المستوى الأعلى.

لقد اعتقدت في الواقع أن الكود الأصلي (في السؤال) فعل ذلك أيضًا ، لأنني اعتقدت أن الإزالة ستزيل بالفعل العقدة ذات المستوى الأعلى بعد العثور على عقدة الورقة الأولى تحتها ؛ ولكن بدلاً من ذلك ، يحاول إزالة عقدة الورقة من مجموعة العقد ذات المستوى الأعلى ، ويتجاهلها فقط إذا لم تتمكن من العثور عليها.

المنشور الأصلي ، رمز غير وظيفي

بادئ ذي بدء ، لماذا تحتاج إلى إزالة العناصر من قائمتك؟

List<string> nodes = new List<string>();

foreach (TreeNode tn in treeViewTab4DirectoryTree.Nodes)
{
    TreeNode temp = tn;

    while (Temp.FirstNode != null)
    {
        Temp = Temp.FirstNode;
    }

    if (!nodes.Contains(Temp.FullPath))
    {
        nodes.Add(Temp.Text);
    }
}

للإجابة على سؤالك الملموس ، على افتراض أن مجموعة العقد تنفذ ienumeries ، استخدم:

List<TreeNode> nodeList = new List<TreeNode>(treeViewTab4DirectoryTree.Nodes);

إذا قررت الالتزام بوجود حلقة ، فيمكنك حفظ Instatiation عن طريق التغيير

TreeNode Temp = new TreeNode();

ل

TreeNode Temp = null;

... أنت لا تستخدم أبدًا الكائن الذي تنشئه ، على الأقل في جزء الكود الذي أظهرته.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top