Silverlight 4: нужна помощь с итерацией - PullRequest
0 голосов
/ 26 мая 2011

У меня проблемы с размышлениями о решении, которое я пытаюсь создать, может быть, кто-то здесь сможет направить меня в правильном направлении.

У меня есть список процессов, принадлежащих процессу, эти процессы могут иметь дочерние элементы, и эти дочерние элементы могут также иметь дочерние элементы и т. Д.

Список выглядит так:

ProcID     ChildOFID
1          0 (means no child)
2          1
3          2
4          3
5          3
6          5

Как видите, в процедуре "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 и т. Д.

Теперь для каждого найденного ребенка мне также нужно проверить, есть ли у него дети и снова выполнить ту же логику, у меня возникли проблемы с созданием этого бесконечного цикла.

Помощь! :)

1 Ответ

1 голос
/ 26 мая 2011

Вы можете создать рекурсивный родительский / дочерний объект и связать его с вашим представлением.Ниже приведен очень простой пример с использованием предоставленных вами данных.

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),
            new KeyValuePair<int,int>(3,2),
            new KeyValuePair<int,int>(4,3),
            new KeyValuePair<int,int>(5,3),
            new KeyValuePair<int,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,0,0">
    <TextBlock Text="{Binding root}"/>
    <ItemsControl ItemsSource="{Binding Children}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <local:RecursiveView DataContext="{Binding}"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</StackPanel>

Изображение вывода:

enter image description here

Я просто поместил поле '30' слева от каждого дочернего элемента, но вы можете настроитьэто будет то, что вы хотите.Не уверен, что это поможет, я просто подумал, что это было забавное испытание:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...