Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#在树列表上自下而上设置活动菜单_C#_List_Tree - Fatal编程技术网

c#在树列表上自下而上设置活动菜单

c#在树列表上自下而上设置活动菜单,c#,list,tree,C#,List,Tree,我有一门课: public class Menu { public Menu() { this.Children = new List<Menu>(); } public string MenuId { get; set; } public string Title { get; set; } public bool IsActive { get; set; } public List<

我有一门课:

public class Menu
{
     public Menu()
     {
          this.Children = new List<Menu>();
     }

     public string MenuId { get; set; }
     public string Title { get; set; }
     public bool IsActive { get; set; }
     public List<Menu> Children { get; set; }    
}
公共类菜单
{
公共菜单()
{
this.Children=新列表();
}
公共字符串MenuId{get;set;}
公共字符串标题{get;set;}
公共bool IsActive{get;set;}
公共列表子项{get;set;}
}
现在我有一个清单:

List<Menu> menu = new List<Menu>();
列表菜单=新建列表();
给定一个MenuId,比如说20,如何递归地将属性IsActive设置为MenuId=20的菜单的所有父级

以下是我的尝试:

  List<Menu> menu = new List<Menu>

        foreach (Menu _menu in menu)
        {
            if (_menu.MenuId == _id)
            {
                _menu.IsActive = true;
                break;
            }
            else
            {
                SetActive(_menu, _id);
            }
        }

    private void SetActive(Menu menu, string _id)
    {
        foreach (Menu _menu in menu.Children)
        {
            if (_menu.MenuId == targetContentId)
            {
                _menu.IsActive = true;
                break;
            }
            else
            {
                SetActive(_menu, _id);
            }
        }
    }
List菜单=新建列表
foreach(菜单中的菜单)
{
如果(\u menu.MenuId==\u id)
{
_menu.IsActive=true;
打破
}
其他的
{
设置活动(_菜单,_id);
}
}
私有void SetActive(菜单,字符串_id)
{
foreach(Menu(Menu.Children中的Menu Menu)
{
如果(_menu.MenuId==targetContentId)
{
_menu.IsActive=true;
打破
}
其他的
{
设置活动(_菜单,_id);
}
}
}

菜单
有一个事件(例如,它可以实现
INotifyPropertyChanged
,但也可以有一个更强类型的
IsActiveChanged
事件)

每当
IsActive
更改时引发该事件

让所有家长订阅其直接子女的事件,并相应地更新自己的
IsActive
值。

类似的内容(假设ID在整个结构中是唯一的):

boolfindandset(int-id,列表菜单)
{
foreach(菜单中的var m)
{
如果(m.MenuId==id)//base case,这就是我们要查找的项
{
m、 IsActive=true;
返回true;
}
else if(m.Children==null | | m.Children.Count==0)
{
return false;//其他基本情况,不再有子项
}
var found=FindAndSet(id,m.Children);//递归
if(found)//如果我们在后代身上找到它
{
m、 IsActive=true;//当我们展开时,集合处于活动状态
返回true;
}
}
返回false;
}

是否应
IsActive
成为
bool
?向下递归,直到找到匹配的项,然后在展开时设置
IsActive
。@DaveZych:是的,它是bool。我的错误。@MattBurland:实际上是我做的(我添加了示例代码)。问题是我不知道如何为该项的父项设置IsActive。现在,当我找到这个项目时,我如何才能从上往下遍历,以便为它的父母设置所有的活动直到根项目?也考虑使用访问者模式:听起来很棒,我以前从未使用过NoItIFyPryTyType。我可以试一试。为什么不呢?只有一个小注释:我替换了
return false;//其他基本情况下,没有更多子项
继续否则,在树的第一个分支上,如果没有更多的子级,它将停止。
bool FindAndSet(int id, List<Menu> menu)
{
    foreach (var m in menu)
    {
        if (m.MenuId == id)    // base case, this is the item we are looking for
        {
            m.IsActive = true;
            return true;
        }
        else if (m.Children == null || m.Children.Count == 0)
        {
            return false;    // other base case, no more children
        }
        var found = FindAndSet(id, m.Children);    // recurse
        if (found)                                 // if we found it in our descendants
        {
            m.IsActive = true;                     // set is active as we unwind
            return true;
        }
    }
    return false;
}