2013-03-19 3 views
1

У меня есть System.Windows.Forms.Treeview элемент управления с флажками для создания дерева разрешений, узлы динамически создаются из записей БД вместе с пользовательскими узлами, добавленными из кода за Allow Add, Allow Delete, Allow Update.Исключение переполнения стека

Проблема в том, что я пытаюсь восстановить узлы проверки из дерева, я получаю StackOverflowException.

Вот мой код:

List<tbl_JobPermission> SaveCheckedPermissions(int _JobID, System.Windows.Forms.TreeNodeCollection theNodes) 
{ 
    using (WFMDBEntities _DBContext = new WFMDBEntities()) 
    { 
     tbl_JobPermission _JopPermissionHelperVar; 
     if (theNodes.Count > 0) 
     { 
      foreach (System.Windows.Forms.TreeNode aNode in theNodes.OfType<System.Windows.Forms.TreeNode>().Where(x => x.Checked == true)) 
      { 
       int _tempJobPermID = int.Parse(aNode.Parent.Name); 
       if (aNode.Name.Contains('_')) 
       { 
        _JopPermissionHelperVar = 
          new tbl_JobPermission() 
          { 
           TblPremition = _tempJobPermID, 
           Tbljob = _JobID 
          }; 
        if (aNode.Name.ToLower().Contains("add")) 
        { 
         _JopPermissionHelperVar.AllowNew = true; 
        } 
        else if (aNode.Name.ToLower().Contains("update")) 
        { 
         _JopPermissionHelperVar.AllowUpdate = true; 
        } 
        else if (aNode.Name.ToLower().Contains("delete")) 
        { 
         _JopPermissionHelperVar.AllowDelete = true; 
        } 

        if (!_JobPermissions.Contains(_JopPermissionHelperVar)) 
        { 
         _JobPermissions.Add(_JopPermissionHelperVar); 
        } 
       } 
       else 
       { 
        _JopPermissionHelperVar = 
          new tbl_JobPermission() 
          { 
           TblPremition = int.Parse(aNode.Name), 
           Tbljob = _JobID 
          }; 
        if (!_JobPermissions.Contains(_JopPermissionHelperVar)) 
        { 
         _JobPermissions.Add(_JopPermissionHelperVar); 
        } 
       } 
       if (aNode.Nodes.Count > 0) 
       { 
        _JobPermissions.AddRange(SaveCheckedPermissions(_JobID, aNode.Nodes)); 
       } 
      } 
     } 
    } 
    return _JobPermissions; 
} 
+1

Любой шанс для одного узла, появляющегося более одного раза в дереве? У каждого узла есть уникальный идентификатор? –

+0

см., Если вы это делаете http://msdn.microsoft.com/en-us/library/wwc698z7.aspx – TalentTuner

+0

@ShadowWizard каждый Узел имеет уникальное имя – user2139774

ответ

1

Я понял, почему я получил исключение StackOverFlow, проблема заключалась не в вызове метода рекурсивно, а в возврате, я возвращал список данных, полученных каждый раз, когда вызываю метод, поэтому элементы списка достигнуты точка, в которой они в два раза резко, так что я сделал простой ==> Я сделал метод тип возвращаемого Пустоты не список [Потому что я буду заполнять этот список (который объявлен в области видимости класса)

void SaveCheckedPermissions(int _JobID, System.Windows.Forms.TreeNode RootNode) 
{ 
    using (WFMDBEntities _DBContext = new WFMDBEntities()) 
    { 
     tbl_JobPermission _JopPermissionHelperVar; 

     foreach (System.Windows.Forms.TreeNode aNode in RootNode.Nodes) 
     { 
      if (aNode.Checked == true) 
      { 
       int _tempJobPermID; 
       int.TryParse(aNode.Name, out _tempJobPermID); 
       _JopPermissionHelperVar = new tbl_JobPermission(); 
       _JopPermissionHelperVar.Tbljob = _JobID; 
       if (aNode.Name.Contains('_')) 
       { 
        int _tempSpecialJobPermID; 
        int.TryParse(aNode.Parent.Name, out _tempSpecialJobPermID); 
        if (_JobPermissions.Where(x => x.TblPremition == _tempSpecialJobPermID).FirstOrDefault() != null) 
        { 
         _JobPermissions.Where(x => x.TblPremition == _tempSpecialJobPermID).FirstOrDefault().TblPremition = _tempSpecialJobPermID; 
         if (aNode.Name.ToLower().Contains("add")) 
         { 
          _JobPermissions.Where(x => x.TblPremition == _tempSpecialJobPermID).FirstOrDefault().AllowNew = true; 
         } 
         else if (aNode.Name.ToLower().Contains("update")) 
         { 
          _JobPermissions.Where(x => x.TblPremition == _tempSpecialJobPermID).FirstOrDefault().AllowUpdate = true; 
         } 
         else if (aNode.Name.ToLower().Contains("delete")) 
         { 
          _JobPermissions.Where(x => x.TblPremition == _tempSpecialJobPermID).FirstOrDefault().AllowDelete = true; 
         } 
        } 
       } 
       else 
       { 
        if (_JobPermissions.Where(x => x.TblPremition == _tempJobPermID).FirstOrDefault() == null) 
        { 
         _JopPermissionHelperVar.TblPremition = _tempJobPermID; 
        } 

       } 

       if (_JobPermissions.Where(x => x.TblPremition == _JopPermissionHelperVar.TblPremition && x.Tbljob == _JopPermissionHelperVar.Tbljob).ToList().Count < 1) 
       { 
        _JobPermissions.Add(_JopPermissionHelperVar); 
       } 
      } 
      SaveCheckedPermissions(_JobID, aNode); 
     } 
    } 
} 
1

У вас есть рекурсивный вызов здесь:

if (aNode.Nodes.Count > 0) 
{ 
    _JobPermissions.AddRange(SaveCheckedPermissions(_JobID, aNode.Nodes)); 
} 

Проверьте, что вы сократили количество узлов, прежде чем рекурсии, запустив под отладчиком.

Я думаю, что если все узлы проверены на определенном уровне, он будет бесконечно возвращаться.

[EDIT]

Это может быть просто, что уровни узлов слишком много. Сколько уровней рекурсии доходит до срыва? Вы можете использовать инструмент Debug.WriteLines?

+1

Ну, я использую рекурсивный вызов для перехода через детей из текущий узел, в противном случае я получаю только корневые узлы, а также проверю на подсчет, если (aNode.Nodes.Count> 0) здесь, чтобы узнать, имеют ли текущий узел дочерние элементы не – user2139774

+0

. Код довольно сложный, поэтому я подумайте, что единственный способ узнать, что происходит, - это сделать один шаг в отладчике. –

+1

Я думаю, что решил проблему рекурсии, я выложу решение достаточно скоро :) – user2139774

Смежные вопросы