Silverlight 4:需要迭代帮助

问题描述

| 我在考虑要尝试构建的解决方案时遇到了麻烦,也许有人可以指导我朝正确的方向发展。 我有一个属于流程流的流程列表,这些流程可能有孩子,而这些孩子也可能有孩子,依此类推。 该列表如下所示:
ProcID     ChildOFID
1          0 (means no child)
2          1
3          2
4          3
5          3
6          5
如您所见,Proc \“ 3 \”包含2个孩子,其中一个(5)也有一个孩子(6)。 我想遍历此列表,并在画布上为其绘制对象。 现在,我有以下代码,但是它要求我为要显示的每个级别编写一个循环。
int prev_location_left = 0;            
        int prev_location_top = 0;

        // Select Last Processstep (has no PreID!)
        var lastProcess = (from p in processlist
                           where p.PreID == 0
                           select p).FirstOrDefault<Processstep>();

        if (lastProcess != null)
        {
            create_processstep(lastProcess.ProcessID,lastProcess.Name,lastProcess.ProcesstypeID,(900),(30),lastProcess.CummulativeCT,lastProcess.WaitingTimeActual,lastProcess.ValueAddTimeActual,lastProcess.ProcessstepTime);

            prev_location_left = 900;
            prev_location_top = 30;
        }

        // Select all the Processsteps that are a child of the last(first) one.
        var listChilds = (from p in processlist
                          where p.PreID == lastProcess.ProcessID
                          select p);


        int childscount = listChilds.Count();
        int cnt = 0;

        foreach (Processstep ps in listChilds)
        {
            create_processstep(ps.ProcessID,ps.Name,ps.ProcesstypeID,(prev_location_left - (150) ),(30 + (60 *cnt)),ps.CummulativeCT,ps.WaitingTimeActual,ps.ValueAddTimeActual,ps.ProcessstepTime);


            var listChilds2 = (from p in processlist
                              where p.PreID == ps.ProcessID
                              select p);

            int cnt2 = 0;

            foreach (Processstep ps2 in listChilds2)
            {
                create_processstep(ps2.ProcessID,ps2.Name,ps2.ProcesstypeID,(prev_location_left - (300) ),(30 + (60 *cnt2)),ps2.CummulativeCT,ps2.WaitingTimeActual,ps2.ValueAddTimeActual,ps2.ProcessstepTime);


                var listChilds3 = (from p in processlist
                                   where p.PreID == ps2.ProcessID
                                   select p);

                int cnt3 = 0;

                foreach (Processstep ps3 in listChilds3)
                {
                    create_processstep(ps3.ProcessID,ps3.Name,ps3.ProcesstypeID,(prev_location_left - (450)),(30 + (60 * cnt2)),ps3.CummulativeCT,ps3.WaitingTimeActual,ps3.ValueAddTimeActual,ps3.ProcessstepTime);
                    cnt3 = cnt3 + 1;
                }


                cnt2 = cnt2 + 1;
            }


            cnt = cnt + 1;
        }
因此,需要执行以下操作: 获取最后一个进程(PreId == 0的那个) 检查他的孩子是什么,并在画布上绘制:左-150,第一个孩子在前30名,第二个孩子在前90名,第三个孩子在前150名,依此类推。 现在,对于找到的每个孩子,我还需要检查他们是否有孩子,并再次执行相同的逻辑,我很难使这成为一个无尽的循环。 救命! :)     

解决方法

您可以创建一个递归的父/子对象,并用视图绑定到该对象。以下是使用您提供的数据的非常基本的示例。 MainPage.xaml
<UserControl x:Class=\"SilverlightApplication4.MainPage\"
xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"
xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"
xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"
xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"
mc:Ignorable=\"d\"
xmlns:local=\"clr-namespace:SilverlightApplication4\"
d:DesignHeight=\"300\" d:DesignWidth=\"400\">

<UserControl.DataContext>
    <local:MainPage_ViewModel/>
</UserControl.DataContext>

<Canvas>
    <local:RecursiveView DataContext=\"{Binding RecursiveObject}\"/>
</Canvas>
MainPage_ViewModel.cs
public class MainPage_ViewModel
{
    public MainPage_ViewModel()
    {
        List<KeyValuePair<int,int>> collection = new List<KeyValuePair<int,int>>()
        {
            new KeyValuePair<int,int>(1,0),new KeyValuePair<int,int>(2,1),int>(3,2),int>(4,3),int>(5,int>(6,5)
        };

        KeyValuePair<int,int> parent = collection.Where(kvp => kvp.Value == 0).First();
        collection.Remove(parent);

        RecursiveObject recursiveObject = new RecursiveObject()
        {
            root = parent.Key
        };

        populateChildren(recursiveObject,collection);

        this.RecursiveObject = recursiveObject;
    }

    public RecursiveObject RecursiveObject 
    {
        get { return recursiveObject; }
        set { recursiveObject = value; }
    }
    private RecursiveObject recursiveObject;


    private void populateChildren(RecursiveObject parent,List<KeyValuePair<int,int>> list)
    {
        List<KeyValuePair<int,int>> children = list.Where(kvp => kvp.Value == parent.root).ToList();
        children.ForEach(child => list.Remove(child));
        children.ForEach(child =>
        {
            RecursiveObject newChild = new RecursiveObject() { root = child.Key };
            parent.Children.Add(newChild);
            populateChildren(newChild,list);
        });
    }
}
RecursiveObject.cs
public class RecursiveObject
{
    public int root { get; set; }
    public List<RecursiveObject> Children 
    {
        get { return children; }
        set { children = value; }
    }
    private List<RecursiveObject> children = new List<RecursiveObject>();
}
RecursiveView.xaml
<UserControl x:Class=\"SilverlightApplication4.RecursiveView\"
xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"
xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"
xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"
xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"
mc:Ignorable=\"d\"
xmlns:local=\"clr-namespace:SilverlightApplication4\"
d:DesignHeight=\"300\" d:DesignWidth=\"400\">

<StackPanel Margin=\"30,0\">
    <TextBlock Text=\"{Binding root}\"/>
    <ItemsControl ItemsSource=\"{Binding Children}\">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <local:RecursiveView DataContext=\"{Binding}\"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</StackPanel>
输出图像: 我只是在每个孩子的左侧放置了一个\ '30 \'的边距,但是您可以将其调整为您想要的任何值。不确定是否有帮助,我只是想尝试一下很有趣:)