在每个循环迭代中创建对象 [英] Create Object in Every Loop Iteration

查看:130
本文介绍了在每个循环迭代中创建对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用内置的z80导航控件,这是演示的链接: Z80导航菜单

I am using z80 navigation control that's built-in and here is the link for demonstration: Z80 Navigation Menu

如果任何人看到该控件,则该控件都有一个对象来创建菜单,如父菜单,并在其下创建子菜单.类似于以下内容:

If anyone see the control, it has an object to create menus like parent menus and under it, child menus. Something like the following:

public List<NavBarItem> sampleDynamicNav; //List of navbar objects
public DemoItems()
{
    //Create object instance here and assign the parent as well child menus here
    sampleDynamicNav = new List<NavBarItem> {
    new NavBarItem {ID = 1, Text = "UserInfo", Icon = new ItemIcon {Default = SampleProject.Properties.Resources.nav_new_home, Hover = SampleProject.Properties.Resources.nav_new_home, Selected = SampleProject.Properties.Resources.nav_new_home}, ToolTip = "tooltip Main Menu", Height = 40,
        Icon = new ItemIcon {Default = SampleProject.Properties.Resources.nav_new_home, Hover = SampleProject.Properties.Resources.nav_new_home, Selected = SampleProject.Properties.Resources.nav_new_home }, ToolTip = "tooltip Desktop"},
        Childs = new List<NavBarItem> {
                    new NavBarItem {ID = 41, Text = "Add/Edit Users", Height = 30 },
                    new NavBarItem {ID = 42, ParentID = 1, Text = "Inactive User", Height = 30}
    };
}

如果我们静态分配菜单,这非常简单.但我坚持使用它,当尝试动态添加它们时,是指从数据库中创建菜单,如下所示:

This is pretty simple if we assign the menus statically. But I stuck with it, when trying to add them dynamically I mean creating the menu from database as follows:

public DemoItems()
{
    foreach (var parent in GetParent("USER-0001"))
    {
          foreach (var child in GetChild(parent.MenuNo))
          {
            sampleDynamicNav = new List<NavBarItem> {
                 new NavBarItem {
                 ID = parent.MenuNo, Text = parent.MenuName, Icon = new ItemIcon {Default =  SampleProject.Properties.Resources.nav_new_home, Hover = SampleProject.Properties.Resources.nav_new_home, Selected = SampleProject.Properties.Resources.nav_new_home}, ToolTip = "tooltip Main Menu", Height = 40,
                 Childs = new List<NavBarItem> {
                                    new NavBarItem {ID = child.MenuNo, ParentID = parent.MenuNo, Text = child.MenuName, Height = 30 },
                           }
                     }
               };
          }
     }
}

使用上面的代码,应该至少在导航栏中获取父菜单.现在,不考虑子菜单,它在导航栏中显示一个父菜单,如下所示:

With the above code, it's supposed to get the parent menus at least in the navigation bar. For now, leaving the child menus aside, it shows one parent menu in the navigation bar as follows:

但是应该像下面这样,因为有两个父菜单,并且使用foreach循环迭代了列表(GetParents()返回对象列表):

But it's supposed to be like the below as there are two parent menus and iterated the list (GetParents() returns a list of object) with foreach loop:

我不知道是否还要为此做其他事情,并且想知道是否可以遍历导航栏的子属性,如下所示:

I don't know if I've to do anything else for it and wondering if I can loop through the child properties of the navigation bar, something as follows:

foreach (var child in GetChild(parent.MenuNo))
{
   Childs = new List<NavBarItem> {
            new NavBarItem {ID = child.MenuNo, ParentID = parent.MenuNo, Text = child.MenuName, Height = 30 },
}

NB :当尝试使用循环迭代子属性时,它立即引发错误.第二个内部循环也起作用,并且也取出子菜单,但是说,父菜单有两个子菜单,此时它返回1.我调试了该列表,它像往常一样返回了两个父菜单,但没有显示在导航栏中.

N.B: When try to iterate the child properties with loop, it throws error right now. The second inner loop works and takes out the child menus as well but say, the parent menu has two sub-menus, it returns 1 at the time. I debugged the list and it returns the two parent menu as usual but doesn't show up in the navigation bar.

GetParents方法:

/**Get Menu Details - Starts**/
public IEnumerable<UserViewModel> GetParent(string empNo)
{
       List<UserViewModel> lstUser = new List<UserViewModel>();

       string query = "SELECT DISTINCT M.PARENT, M.MENUNO, M.MENUNAME FROM (SELECT DISTINCT M.MENUNO, M.MENUNAME, M.PARENT " +
                      "FROM USER_DETAILS U INNER JOIN USER_GROUP_DETAILS UG ON UG.EMPNO = U.EMPNO " +
                      "INNER JOIN ASSIGN_MENU_DETAILS AM ON AM.GROUPNO = UG.GROUPNO INNER JOIN MENU_DETAILS M " +
                      "ON M.MENUNO = AM.MENUNO WHERE U.EMPNO = '" + empNo + "' " +
                      "UNION ALL " +
                      "SELECT DISTINCT M.MENUNO, M.MENUNAME, " +
                      "M.PARENT FROM MENU_DETAILS M " +
                      "INNER JOIN MENU_DETAILS C " +
                      "ON C.PARENT = M.MENUNO) m WHERE M.PARENT = '0' ORDER BY M.PARENT";

        DataTable dt = SelectData(query);

        if (dt != null && dt.Rows.Count > 0)
        {
            foreach (DataRow dr in dt.Rows)
            {
                UserViewModel bo = new UserViewModel();
                bo.Parent = Convert.ToInt32(dr["PARENT"].ToString());
                bo.MenuNo = Convert.ToInt32(dr["MENUNO"].ToString());
                bo.MenuName = dr["MENUNAME"].ToString();

                lstUser.Add(bo);
            }
        }
   return lstUser;
}
/**Get Menu Details - Ends**/

推荐答案

您可以创建以下辅助方法,并使用它们来创建List<NavBarItem,以接受任何类型的数据源作为输入,包括DataTableList<YourEntity>或其他任何IEnumerable<T>.

You can create the following helper methods and use them to create a List<NavBarItem accepting any kind of data sources as input, including DataTable, List<YourEntity> or anything else which is IEnumerable<T>.

因此,无论您拥有什么数据存储,都可以使用以下方法.

So regardless of the data store which you have, you can use the following methods.

它依赖于创建树的递归算法.为了从任何种类的数据源创建树,您需要具备以下信息:

It relies on a recursive algorithm for creating tree. For creating a tree from any kind of data source, you need to have the following information:

  1. 数据源
  2. 如何检测数据源中的项目是否为根项目
  3. 如何在数据源中查找某项的子项
  4. 如何从数据源项目创建树项目.

以下方法通过询问上述信息来创建NavBarItem层次结构的列表:

The following method creates a list of NavBarItem hierarchy by asking about above information:

private IEnumerable<NavBarItem> GetNavBarItems<T>(
    IEnumerable<T> source,
    Func<T, Boolean> isRoot,
    Func<T, IEnumerable<T>, IEnumerable<T>> getChilds,
    Func<T, NavBarItem> getItem)
{
    IEnumerable<T> roots = source.Where(x => isRoot(x));
    foreach (T root in roots)
        yield return ConvertEntityToNavBarItem(root, source, getChilds, getItem); ;
}

private NavBarItem ConvertEntityToNavBarItem<T>(
    T entity,
    IEnumerable<T> source,
    Func<T, IEnumerable<T>, IEnumerable<T>> getChilds,
    Func<T, NavBarItem> getItem)
{
    NavBarItem node = getItem(entity);
    var childs = getChilds(entity, source);
    foreach (T child in childs)
        node.Childs.Add(ConvertEntityToNavBarItem(child, source, getChilds, getItem));
    return node;
}

示例

我假设您已将数据加载到以下结构中:

I assume you have loaded data into the following structure:

var dt = new DataTable();
dt.Columns.Add("Id", typeof(int));
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("ParentId", typeof(int));

dt.Rows.Add(1, "Menu 1", DBNull.Value);
dt.Rows.Add(11, "Menu 1-1", 1);
dt.Rows.Add(111, "Menu 1-1-1", 11);
dt.Rows.Add(112, "Menu 1-1-2", 11);
dt.Rows.Add(12, "Menu 1-2", 1);
dt.Rows.Add(121, "Menu 1-2-1", 12);
dt.Rows.Add(122, "Menu 1-2-2", 12);
dt.Rows.Add(123, "Menu 1-2-3", 12);
dt.Rows.Add(124, "Menu 1-2-4", 12);
dt.Rows.Add(2, "Menu 2", DBNull.Value);
dt.Rows.Add(21, "Menu 2-1", 2);
dt.Rows.Add(211, "Menu 2-1-1", 21);

然后将其转换为List<NavBarItem>,您可以使用以下代码:

Then to convert it to a List<NavBarItem>, you can use the following code:

var source = dt.AsEnumerable();
var list = GetNavBarItems(
        source,
        (r) => r.Field<int?>("ParentId") == null,
        (r, s) => s.Where(x => x.Field<int?>("ParentId") == r.Field<int?>("Id")),
        (r) => new NavBarItem()
        {
            ID = r.Field<int>("Id"),
            Text = r.Field<string>("Name"),
            ParentID = r.Field<int?>("ParentId")
        }).ToList();

结果,您将具有以下结构:

As a result, you will have the following structure:

Menu 1
   Menu 1-1
       Menu 1-1-1
       Menu 1-1-2
   Menu 1-2
       Menu 1-2-1
       Menu 1-2-2
       Menu 1-2-3
       Menu 1-2-4
Menu 2
    Menu 2-1
        Menu 2-1-1

注意

对于不想安装软件包但想要测试结构的用户,可以使用以下NavBarItem类:

For those who don't want to install the package, but want to test the structure, you can use the following NavBarItem class:

public class NavBarItem
{
    public NavBarItem()
    {
        Childs = new List<NavBarItem>();
    }
    public int ID { get; set; }
    public int? ParentID { get; set; }
    public string Text { get; set; }
    public List<NavBarItem> Childs { get; set; }
    public override string ToString()
    {
        return Text;
    }
}

这篇关于在每个循环迭代中创建对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆